#Avian Physics

1 messages Β· Page 12 of 1

trail sparrow
#

I'll start reading the parry code

sleek thicket
#

by rewriting i mean barry, just switching nalgebra to glam and bevy math

cinder summit
#

Reading parry's code does hurt actually πŸ‘€

sleek thicket
#

and yeah i have to agree there

vestal minnow
#

I wasn't even born yet πŸ‘€

trail sparrow
#

I saw Bevy 0.13 has some collision detection built in now??

sleek thicket
#

yep

#

aabb, boundingsphere and ray

vestal minnow
#

yes-ish but actually no

cinder summit
#

Not really collision detection but bounding volumes yea

sleek thicket
#

primitive shapes kinda have some methods like in parry from what i understand

vestal minnow
#

bounding volumes and intersection tests and ray casts against them

cinder summit
trail sparrow
#

I guess for primative shaped colliders, collision detection isn't that difficult

sleek thicket
#

it's difficult.

vestal minnow
#

it kinda is unless you do just ball-ball collisions

cinder summit
#

Sphere - Any shape is simple however ... As long as the signed distance function and gradients are known for that shape

sleek thicket
#

being a rust noob shouldn't prevent reading/understanding parry code, but it's difficult.

cinder summit
vestal minnow
cinder summit
#

Honestly you're better of with geometry knowledge than rust knowledge when trying to understand anything collisions anyway ... Especially if there's not a lot of docs

#

Also I feel like the biggest help for bevy_xpbd optimization might actually be pinpointing the biggest bottlenecks

trail sparrow
#

I guess there are two things: Are two convex objects touching(not too hard), by how much are they touching(much harder).

vestal minnow
#

well for 1 you need gjk already for a lot of shapes

sleek thicket
cinder summit
trail sparrow
#

My thought is that you'd break down any non-convex shapes into simpler primatives. Then use some bounding box to avoid testing everything against everything.

vestal minnow
vestal minnow
#

which is how you build more complex shapes

#

unless you're using trimeshes

#

or SDFs :P

cinder summit
#

convex decomposition is not simple tho

#

Also yea SDFs best πŸ‘€

cinder summit
#

The most fun part is that you need all of these collisions to function under unreasonable constraints like: It needs to support thousands of entities on a single core at 3GHz

sleek thicket
#

either way, let me repeat myself

#

if @trail sparrow wants to try then it's a good start even if it's just rays/boxes/balls vs balls/boxes

cinder summit
#

Watch as someone actually gives me torus gradients and I'll be struggling with this for weeks

vestal minnow
cinder summit
#

Oh no

trail sparrow
#

BOOM

vestal minnow
#

you haven't found that? πŸ˜‚

#

it's the first result lmao

cinder summit
#

Because I didn't want to find it πŸ‘€

vestal minnow
#

it's by iq too

#

of course

#

who else

trail sparrow
#

I need to learn how to use a render pipeline to do this in Bevy πŸ˜„

#

Who is IQ?

cinder summit
#

It's someone that publishes a lot of info about shape related stuff

vestal minnow
cinder summit
#

Especially involving raymarching and raytracing

sleek thicket
#
trail sparrow
#

I'm gonna spend some time on his YouTube today rather than rewriting parry

vestal minnow
#

wait that's the same guy who made the snail image and that Greek temple thonk I've seen them but never knew it was him

cinder summit
#

No one should be rewriting parry anyway ... Only @vestal minnow would start such insanity πŸ˜‚

cinder summit
sleek thicket
#

a new SDF convert acquired

trail sparrow
sleek thicket
#

no

trail sparrow
#

What's wrong with Parry?

sleek thicket
#

switch from nalgebra to bevy math and glam

vestal minnow
#

nah Parry is pretty optimized already

#

generally

cinder summit
vestal minnow
cinder summit
#

Tho parry has a few major flaws: The QBVH doesn't like updating ... And there's a lot of dynamic dispatch ... Which I think we can technically work around πŸ€”

vestal minnow
#

and the codebase has questionable characteristics like 500+ warnings or errors

cinder summit
#

But then the code where bevy_xpbd uses parry does a ton of unnecessary allocs, stores things multiple times, probably doesn't have some very basic early out logic, etc ... And it's also ran every substep πŸ˜‚

trail sparrow
vestal minnow
#

I have the core of that migration to bevy_math done in my fork already

sleek thicket
sleek thicket
cinder summit
vestal minnow
#

yeah that, and fix some potential bugs I caused

sleek thicket
#

@trail sparrow if you start a new library and just handle the basic stuff you can understand, it'll probably already be useful for simpler games

vestal minnow
#

at least inertia is a bit wrong

cinder summit
#

But yea I'm pretty sure that the quickstart guide to optimizing bevy_xpbd looks like this:

  1. Create a game where a lot of collisions happen
  2. Figure out the thing that takes the most frametime
  3. Fix that thing
vestal minnow
#

about half-done

cinder summit
cinder summit
#

Ah so you want boxes ... Yea my sdf collisions don't support those yet

vestal minnow
#

we kinda have that with the bounding stuff already

cinder summit
#

Maybe soon thonk

vestal minnow
#

and no contact data πŸ˜‚

cinder summit
#

If only spherecasts against AABBs, OBBs and benchmarks so we can do that Vec3A thing

vestal minnow
sleek thicket
#

mhm

vestal minnow
#

Parry uses some kind of SAT, support mapping, point projection and more for it

#

and closest points stuff (although it's just segment-segment which doesn't require gjk)

trail sparrow
#

The Gilbert–Johnson–Keerthi distance algorithm is a method of determining the minimum distance between two convex sets, first published by Elmer G. Gilbert, Daniel W. Johnson, and S. Sathiya Keerthi in 1988. Unlike many other distance algorithms, it does not require that the geometry data be stored in any specific format, but instead relies sol...

vestal minnow
#

yeah

#

finds the closest points (or distance) between two arbitrary convex shapes

trail sparrow
#

I wish algorithms would be named something more related to their ideas than the authors...

vestal minnow
#

EPA is, it's the "Expanding Polytope Algrorithm"... you just need to know what that means

#

it's used for computing penetration depth and normals after GJK

#

(for penetrating contacts)

trail sparrow
#

So, back to the start of this conversation... does parry need to be replaced, reworked or used differently to improve XPBD performance?

#

Is there a non-ocean burning approach?

vestal minnow
#

for performance specifically, mainly used differently, but there are other unrelated bottlenecks too

#

but bevy_xpbd does need glam-based collision detection instead of parry if we ever want to upstream official physics

sleek thicket
trail sparrow
vestal minnow
#

because we don't want nalgebra in Bevy's dependency tree

trail sparrow
#

You already did that work in a fork though?

vestal minnow
#

needs glam-based collision detection

sleek thicket
#

is there anyone else working on native bevy physics though?

vestal minnow
vestal minnow
#

but it might not be called bevy_xpbd

trail sparrow
sleek thicket
#

there's nise but that's more of a fork/extension of xpbd from what i understand

vestal minnow
#

nise uses normal xpbd

cinder summit
#

Yea, I don't do physics just collisions

vestal minnow
sleek thicket
#

so yeah, there's no competition for official bevy physics

trail sparrow
cinder summit
#

By the time bevy is ready for a bevy_physics, bevy_xpbd won't use xpbd anymore anyway with how things are going thonk

sleek thicket
#

bevy_heavy

#

C:<

vestal minnow
trail sparrow
#

Gotcha

vestal minnow
#

like Direction3d::new_and_length_with_min

#

beautiful name

trail sparrow
#

Well, I was gonna suggest we could all help push barry forward

#

Maybe could start by making a private repo or something with issues for the major tasks to be accomplished.

vestal minnow
#

I also have bevy_peck which is a very very very WIP collision detection library made from scratch

sleek thicket
#

Support using Bevy's threadpool instead of rayon to unblock threads when using Bevy
wait, parry blocks threads?

vestal minnow
#

that might not be a thing anymore

#

but iirc rayon used separate threads while bevy used its own task pools

#

I think they can share now?

#

not sure

cinder summit
vestal minnow
#

It normalizes the vector, returning the original length, but returns an error if the length is below the given threshold (new_and_length threshold is just 0 iirc)

#

but for Bevy's direction types

#

Parry uses it in e.g. gjk

#

for safety reasons

sleek thicket
#

wait, it normalizes but returns the original length?

vestal minnow
#

yeah because that's often valuable

#

the new length would just be 1 :P

#

it's

let vec = Vec3::X * 2.0;

// In method
let length = vec.length();
let normalized = vec / length;
return (normalized, length);
sleek thicket
#
    pub fn try_new_and_get(mut value: T, min_norm: T::Norm) -> Option<(Self, T::Norm)>
    where
        T::Norm: RealField,
    {
        let sq_norm = value.norm_squared();

        if sq_norm > min_norm.clone() * min_norm {
            let n = sq_norm.simd_sqrt();
            value.unscale_mut(n.clone());
            Some((Unit { value }, n))
        } else {
            None
        }
    }
vestal minnow
#

yeah

#

that's the actual optimized version with the threshold but the idea is the same

sleek thicket
#

is Norm same as Direction3d?

vestal minnow
#

norm is length

#

Unit<Vector3> would be Direction3d

#

or UnitVector3

sleek thicket
#

oh, i actually like that one

#

norm doesn't make sense

vestal minnow
#

it's a mathematical term

#

In mathematics, a norm is a function from a real or complex vector space to the non-negative real numbers that behaves in certain ways like the distance from the origin: it commutes with scaling, obeys a form of the triangle inequality, and is zero only at the origin. In particular, the Euclidean distance in a Euclidean space is defined by a nor...

sleek thicket
#

well, i'm not a mathematician so it still doesn't makes sense πŸ₯΄

vestal minnow
#

yeah

#

specifically, it's the Euclidean norm in this context

#

but Nalgebra supports complex numbers and stuff too

sleek thicket
#

how does a vector get negative though, doesn't it just flip direction?

#

or is that not a vector

vestal minnow
#

what are you referring to as a vector

sleek thicket
#

wait, norm is just a positive float?

vestal minnow
#

yes here it's just the length of the vector

sleek thicket
#
    pub fn try_new_and_get(mut value: vec3, min_length: f32) -> Option<(Self, f32)>
    {
        let sq_length = value.length_squared();

        if sq_length > min_length.clone() * min_length {
            let length = sq_length.sqrt();
            value.unscale_mut(length.clone());
            Some((Direction3d { value }, length))
        } else {
            None
        }
    }
vestal minnow
#

vec.length() is the same as vec.length_squared().sqrt()

#

so it splits it up to early out if possible

#

yeah the generic nature of this makes it hard to read

#

but the length of e.g. a 3D vector mathematically is either:

sleek thicket
#

i mean, i gotta give credit to sebcrozet for coming up with this stuff

#

but i like simplicity ._.

vestal minnow
#

The length of a vector is

|v| = sqrt(dot(v, v))

which in 3D becomes

|v| = sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
#

so the sqrt can be split out

sleek thicket
#

hey, i remember that from middle school math

vestal minnow
#

this is for a generic matrix, so it just iterates over the columns (which are essentially vectors) and adds up the squared lengths (or norms)

#

so ultimately it's pretty simple

#

a Vector3 is just a single column, i.e. a 3x1 matrix

vestal minnow
sleek thicket
#

nvm

#

so it's basically a simd .length_squared

sleek thicket
#
pub fn dot(self, rhs: Self) -> f32 {
        (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
    }
#
    pub fn length_squared(self) -> f32 {
        self.dot(self)
    }
#

glam doesn't simd?

vestal minnow
#

it compiles to different code on different architectures, that's just the "basic" rust version intended to be readable

sleek thicket
#

oh, then yeah. i like this.

#

this is how it should be.

vestal minnow
#

I think this is what the simd version is

/// Calculates the vector 3 dot product and returns answer in x lane of f32x4.
#[inline(always)]
pub(crate) fn dot3_in_x(lhs: f32x4, rhs: f32x4) -> f32x4 {
    let x2_y2_z2_w2 = lhs * rhs;
    let y2_0_0_0 = simd_swizzle!(x2_y2_z2_w2, [1, 0, 0, 0]);
    let z2_0_0_0 = simd_swizzle!(x2_y2_z2_w2, [2, 0, 0, 0]);
    let x2y2_0_0_0 = x2_y2_z2_w2 + y2_0_0_0;
    x2y2_0_0_0 + z2_0_0_0
}
#

intrinsics are horrible to read

sleek thicket
#

it's pretty simple when it's not buried behind arcane types and function names

trail sparrow
#

Gotta say, I'm not a fan of the word swizzle even if it's meaningful here.

vestal minnow
#

I can say that it gets a lot worse

trail sparrow
#

Just the word... sounds dirty in a not fun way

#

lol

#

But I'm reading about it now and looks like it's a legit industry term

sleek thicket
#

yep

trail sparrow
#

I cannot wait to be finished with this game I'm working on. I've played it too much while debugging it and I wanna play the "lets make a new game" game. 😐

sleek thicket
#

classic

#

that's how you know you got something good though

trail sparrow
#

I hope you'll all play it if you have iPhones though

sleek thicket
#

why iphone

trail sparrow
#

Just what I'm focusing on developing for atm

vestal minnow
vestal minnow
trail sparrow
vestal minnow
#

yeah

sleek thicket
#

i had an iphone for a couple months, never got used to it and went back to android

trail sparrow
#

I wanna port to Android, but I also want to run away from this game atm.

vestal minnow
#

fyi this is probably getting a bit off-topic for a bevy_xpbd crate-help channel πŸ˜…

trail sparrow
#

So I'll drop it in the App store and put up a couple YT videos of gameplay. bevy_xpbd is a huge part of the gameplay though, so I'll be mentioning you and others in the credits

vestal minnow
#

and thanks ❀️

trail sparrow
#

lol ofc

cinder summit
#

Imagine you credit bevy_xpbd nicely, when suddenly NVIDIA be like: πŸ‘€

vestal minnow
cinder summit
#

Isn't that just for Solver2d which is more of a research thing?

vestal minnow
#

yes

#

you could say bevy_xpbd is research πŸ‘€

cinder summit
#

Ah yes ... Libraries and games in bevy are just πŸ§ͺ

vestal minnow
#

I need to take enough elements from the TGS soft solver and other solvers into XPBD to make it a novel approach

cinder summit
#

How possible is it to combine them?

#

I like that "no velocity" penetration solving from NGS, and TGS soft seems a lot more stable

#

But then for distance constraints you want XPBD πŸ€”

vestal minnow
#

On the Ten Minute Physics Discord Erin was discussing XPBD stuff with others, and someone managed to use a block solver for joints to make them more stable

#

And you could maybe somehow take the "soft" constraint part

#

i.e. formulate spring-like damping into the constraints

#

also solving e.g. x and y for joints separately unlike the XPBD paper can be more stable

#

based on some test

cinder summit
#

But yea definitely could be interesting to combine some approaches to make a library that has exactly the properties you'd want in a game engine

vestal minnow
#

SPBD = Soft Position-Based Dynamics

cinder summit
#

We need Signed Distance Based Dynamics thonk

vestal minnow
#

SDFBD

#

yeah lmao

#

constraints as SDFs...

#

I guess in a way, constraint functions could be seen as SDFs already

#

and equality constraints minimize the distance by moving opposite to the gradient

#

(of course that's not really an SDF tho)

cinder summit
#

Minimizing error by moving based on gradients ... Is this ... Machine learning? thonk

vestal minnow
#

GPTBD coming soonβ„’

cinder summit
#

Gradient descent into madness thonk

cinder summit
vestal minnow
#

Why use a physics engine at all? Just generate a continuous video stream of the simulation with AI

#

Player inputs change the neural network's input parameters

#

Latency of a few seconds, but I'm sure that's fine

#

also iq is so well known that the Wikipedia article on SDFs mentions him

#

Maybe your game will get popular enough to get listed as an example of using SDFs thonk

trail sparrow
#

@vestal minnow , I'm noticing bevy_hanabi seems to interfere with the debugging visualization plugin

vestal minnow
#

how?

trail sparrow
#

I'm trying to figure it out now. But I have something like this:

                if let Some(portal_effect) = &particle_effects.blue_explosion {
                    println!("creating force ball at: {:?} with portal", world_position);
                    commands.spawn((
                        /*
                        MaterialMesh2dBundle {
                            mesh: meshes.add(shape::Circle::new(ball_radius)).into(),
                            material: materials.add(ColorMaterial::from(Color::rgb(3.2, 2.3, 0.4))),
                            //transform: Transform::from_xyz(world_position.x, world_position.y, 1.0),
                            transform: Transform::from_xyz(world_position.x, world_position.y, 1.0)
                                .with_scale( (1. * Vec2::ONE).extend(1.)),
                            ..default()
                        },
                        */
                        ParticleEffectBundle {
                            effect: ParticleEffect::new(portal_effect.clone())
                                .with_z_layer_2d(Some(0.1)),
                            transform: Transform::from_xyz(world_position.x, world_position.y, 1.0)
                                .with_scale( (10. * Vec2::ONE).extend(1.)),
                            ..default()
                        },
                        //*/
                        Collider::ball(200.),
                        RigidBody::Static,
                        Friction::new(0.0),
                        Restitution::new(0.0001),
                        ColliderDensity(1.0),
                        Controllable,
                        Sensor,
                        ForceBall {
                            start_time: time.elapsed(),
                        },
                    ));
                }

#

If I use use MaterialMesh2dBundle, the ball collider shows up and stays around, but if I use ParticleEffectBundle the ball collider is only visible for a couple frames.

#

Everything still works though.

vestal minnow
#

0.13 supports separate gizmo config groups and bevy_xpbd has its own, so hanabi can't change that in any way

#

unless your version of bevy_xpbd didn't have that yet

trail sparrow
#

One other thing...

#

If I don't have a ParticleEffectBundle or a MaterialMesh2dBundle, but just a Transform, then the ball stays centered at (0,0)

vestal minnow
#

Bevy needs GlobalTransform too

trail sparrow
#

Ah, got it..

vestal minnow
#

they're grouped in TransformBundle

#

and SpatialBundle

trail sparrow
#

Thank you that works now

cinder summit
#

I enable bevy_sprite in my project and suddenly I get an extra set of gizmos? πŸ€”

vestal minnow
cinder summit
#

It's drawing all the aabbs, but from a different perspective

#

I wonder if it's because I have a Camera2d for kayak_ui πŸ€”

vestal minnow
#

Maybe?

#

I think gizmos can be configured to draw to specific cameras only or something

edgy light
cinder summit
#

@vestal minnow Have you ever thought about collider assets? I feel like it could be useful for hotreloading later and avoiding having duplicate mesh colliders in memory ... But idk how fast fetching the assets for every entity would be, considering the dynamic dispatch on parry I guess it already has to fetch them from meory tho πŸ€”

sacred sigil
#

do you have any idea if soft bodies are part of bevy-xpbd, or how one would even begin to go about implementing them?

fair fractal
#

but depending on the amount of particles you're trying to simulate, probably not very efficiently

sacred sigil
#

I'm hoping to achieve a 2d simulation of metal, being able to pound it and such as in a forge; so it definitely wouldn't be very efficient.

sacred sigil
vestal minnow
#

I believe the term for this would be plasticity. I don't know many physics engines that support it, except NPhysics, but that was superseded by Rapier, which doesn't support soft bodies yet.

Soft bodies aren't on the short term roadmap for bevy_xpbd since there are still many other things that are more important for typical gamedev, but I do find soft bodies to be very interesting and want to try and implement them at some point.

For XPBD soft bodies in general, blackedout01 has a really nice YouTube series: https://youtu.be/MgmXJnR62uA?si=Q7yS3UsP9zrPRgqh

There are also several papers on the topic, and Matthias Muller (one of the authors of XPBD) has resources and examples at https://matthias-research.github.io/pages/tenMinutePhysics/index.html

I'm not sure how plasticity is typically handled, but one idea would be to detect when constraint forces exceed some threshold, and to permanently reduce the target distances for the corresponding distance constraints (and target volumes for volume constraints?)

I wrote a simple soft body cube in C/C++ using the extended Position-Based Dynamics method for my first devlog episode.

The mentioned papers (and a lot more)
https://matthias-research.github.io/pages/publications/publications.html

SDL Template
https://github.com/blackedout01/sdl-gl-template

0:00 Introduction
0:41 PBD overview
1:11 Game
1:25 T...

β–Ά Play video
#

@sacred sigil ^

vestal minnow
#

The current blocker for it is the thing where we'd probably need to derive Reflect for Collider, but... Parry

#

And yeah I don't know what the cost of doing colliders.get(collider_handle) everywhere would be, but we'll just have to try

#

Colliders as assets could be nice API-wise with the primitives too, like you could just do

colliders.add(Circle::new(0.5))
sleek thicket
#

i think for blacksmithing you wouldn't even need soft body, just deform mesh by moving verts based on force applied

#

or see how car crash sims work

vestal minnow
#

bevy_heavy was mostly meant to be just mass props for Bevy's primitives πŸ˜‚

sleek thicket
#

it's a good name for physics in general though

#

nothing can be heavy without physics

vestal minnow
#

"heavy" can be interpreted as overhead, and that might not be good for physics

sleek thicket
#

but physics are an overhead, maybe that's even a good thing

#

like who was it that tried to use physics for something that can be done with plain A*

#

and if everything goes well, calling rapier heavier than heavy would be satisfying

#

why do i sound like i'm trying to sell a rebrand lmao πŸ˜‚

vestal minnow
#

if we switch solvers then we might need a rebrand anyway

#

(or become solver-agnostic)

sleek thicket
#

and collision lib agnostic

#

no idea if that's even possible though

#

or is it already

#

it is, isn't it? i just remembered nise

#

good morning btw.

vestal minnow
#

thanks, it's already 12:30 for me tho

sleek thicket
#

my brain is slow in the mornings, evenings and nights. sometimes day too.

vestal minnow
# sleek thicket and collision lib agnostic

Colliders are generic already, so you can pretty easily make custom colliders, but we can't really have a single Collider struct that would support several different collision libs

#

Collider representations can differ, like with Nise's SDF colliders you can just extrude and cut shapes, which doesn't really work with normal colliders

dreamy viper
#

@vestal minnow on 0.4.0 with feature serialize I get this error
```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait Deserialize<'_> is not implemented for configuration::ContactGizmoScale

vestal minnow
#

it technically is, but not officially announced because irl stuff got in the way just as I was about to release posts and stuff

#

turns out it was enough for Nalgebra to update, although I'm not sure why it works because Parry should still be using the old version

sleek thicket
#

oh

vestal minnow
cinder summit
vestal minnow
#

I'm annoyed that CI doesn't catch issues like this at the moment

cinder summit
#

Does CI not compile with and without serialize?

vestal minnow
#

CI compiles, but I think it just might not have serialize

#

should add it probably

dreamy viper
#

thanks

sacred sigil
vestal minnow
#

Alright, 0.4 has officially been announced: #crates message

daring hawk
#

after migrating to 0.4 all my colliders spawn at the origin when the entities they belong to don't, is it a just me issue?

vestal minnow
#

Are you adding PhysicsPlugins normally?

#

i.e. PhysicsPlugins::default()

daring hawk
#

changed nothing from 0.3 besides calling it sphere instead of ball

#

yes ::default()

#

added the debug plugin to see what was going on

vestal minnow
#

Weird πŸ€” At least all of the examples are working normally, like this one

daring hawk
#

must be a case of me

#

Just wanted to check in

vestal minnow
#

Could you show an example of how you're spawning some entity?

daring hawk
#

and all 10 colliders spawn at origin

vestal minnow
#

What do you get with just something like this?

commands.spawn((
    PbrBundle {
        mesh: meshes.add(Sphere::new(0.5).mesh().uv(32, 18)),
        material: materials.add(Color::rgb(0.1, 1.0, 0.2)),
        transform: Transform::from_xyz(5.0, 2.0, -1.0),
        ..default()
    },
    Collider::sphere(0.5),
));
#

For me it's positioned correctly

vestal minnow
daring hawk
#

no, they are each spawned individually

#

ill try spawning jsut one

#

collider at origin still

#

Might be bc I use SystemSets?

#

Only thing is that it all worked fine in 0.12 with 0.3

vestal minnow
#

Where do you spawn them? Scheduling-wise

daring hawk
#

In my loading system set that runs when entering gamestate loading

#

idk if it should interfer with xpbd

vestal minnow
#

Does this happen in Update?

daring hawk
#

yes

vestal minnow
#

then it shouldn't be an issue...

#

Well, here's a minimal example that should definitely work if you run this

use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*;

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

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands.spawn((
        PbrBundle {
            mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)),
            material: materials.add(Color::rgb(1.0, 0.75, 0.0)),
            ..default()
        },
        Collider::sphere(0.1),
    ));

    commands.spawn((
        PbrBundle {
            mesh: meshes.add(Sphere::new(0.5).mesh().uv(32, 18)),
            material: materials.add(Color::rgb(0.1, 1.0, 0.2)),
            transform: Transform::from_xyz(5.0, 2.0, -1.0),
            ..default()
        },
        Collider::sphere(0.5),
    ));

    commands.spawn(PointLightBundle {
        point_light: PointLight {
            intensity: 2_000_000.0,
            range: 50.0,
            shadows_enabled: true,
            ..default()
        },
        transform: Transform::from_xyz(0.0, 15.0, 0.0),
        ..default()
    });

    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(-7.0, 9.5, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}
#

should render this

daring hawk
#

Thanks πŸ™‚

vestal minnow
#

Hmm, okay I can actually reproduce the issue πŸ€”

daring hawk
#

Rad

vestal minnow
#

It is a thing where spawning in Update makes it not work for whatever reason

daring hawk
#

aha

#

Makes it hard for me to come up with a work around for now

#

maybe inserting collider post spawn?

vestal minnow
#

probably not...

#

I'll try to find the issue

daring hawk
#

yeah didn't change anything

vestal minnow
daring hawk
#

Appreciate your help and work

vestal minnow
#

You can make it kinematic or static for now

daring hawk
#

cool!

#

Yep, that did it, thank you!

vestal minnow
#

np!

#

I'll still fix the actual issue though, I might have found it

#

seems to be a scheduling thing

daring hawk
#

Makes sense

#

since they did change that apply deferred thing in 0.13

#

although we didn't have to do anything about it

vestal minnow
#

I think that's unrelated here, I'm just missing a transform propagation thing for colliders without rigid bodies

daring hawk
#

aha

vestal minnow
#

0.4 had a pretty big rework for how colliders are handled internally and this was just an oversight

daring hawk
#

cool

#

Yeah I have not looked too much under the hood on xpbd

#

I love how easy it is to add to a bevy project

#

was surprised you migrated so quickly

#

was planning on maybe going without it xD

vestal minnow
#

hehe

#

yeah I had the PR mostly ready for a pretty long time in advance

daring hawk
#

Pretty cool

vestal minnow
#

so I mostly needed to finish up some final things and write the announcement and migration guide once 0.13 actually released

daring hawk
#

ahhh very nice

#

I'm really impressed with your work! Excited to follow along

vestal minnow
#

Thanks πŸ˜„ I appreciate it a lot :)

sleek thicket
#

migrating xpbd wasn't as bad as lwim

daring hawk
#

I

#

can't imagine

#

I'm hesitant to use it bc of how it looks at first glance lol

sleek thicket
daring hawk
#

Ah

sleek thicket
#

i'm not even done yet and i think i'll just go to sleep

vestal minnow
sleek thicket
#

i fixed the last error 5 mins ago

vestal minnow
#

ah alr

sleek thicket
#

didn't even build it

vestal minnow
#

good night, I also need to go sleep very soon

sleek thicket
#

very soon means like 5 hrs ago?

vestal minnow
#

mhmm

#

eh, 4am isn't too bad

daring hawk
#

yikes!

#

well time is just a concept anyhow

vestal minnow
#

okay @daring hawk I pushed a quick fix to the main branch, could you maybe try if it works with that now?

[dependencies]
bevy_xpbd_3d = { git = "https://github.com/Jondolf/bevy_xpbd", branch = "main" }
#

(without RigidBody on the entities)

daring hawk
#

Yes. One sec

#

@vestal minnow That did it

dusty knot
#

Is there support for a point collider?

sleek thicket
dusty knot
#

I'm trying to reimplement a collider with a bullet hell style "all that matters is if the center is in the bad"

sleek thicket
#

then intersection is probably fine

#

and makes it even easier since you won't even need to sort out collisions

vestal minnow
#

Could also use a circle collider with a tiny radius

vestal minnow
dusty knot
dusty knot
sleek thicket
dusty knot
#

not if you have multiple players!

sacred sigil
#

I have a question regarding the simulation of soft bodies. They are fundamentally made up of points/particles/entities, of course, but I'm not sure what to use as particles. is there some sort of bundle or other thing provided by bevy_xpbd or bevy that I could use? or if not, how would I go about creating something to use for this?

vestal minnow
# sacred sigil I have a question regarding the simulation of soft bodies. They are fundamentall...

So I made a very rough soft body experiment a long time ago: #showcase message

IIRC this was simply using dynamic rigid bodies as particles, with distance constraints connecting them, and a "global volume constraint" to simulate a kind of pressure inside the ball.

Each particle was its own entity with a RigidBody::Dynamic component, and I think I just used ball colliders (there's probably a much better way to handle collisions, I just haven't looked into it much yet).

This is convenient since it Just Worksβ„’ with other physics functionality, and it could be fine for a basic 2D simulation without huge amounts of particles. But for proper soft bodies, I'm unsure if using a separate entity for each particle is the ideal approach; it might be more efficient to have something more custom-made where you e.g. store all particles in an array in a SoftBody component and simulate them manually. That's a lot more work though.

#

But no, bevy_xpbd doesn't really have a component or bundle specifically for particles at the moment. It could be useful when we add some kind of built-in cloth or soft bodies though

sacred sigil
vestal minnow
#

Not publicly at the moment but I should have it somewhere... it's for an old version of Bevy though and very WIP and messy

#

I'll try to find it

sacred sigil
#

thanks so much! and thanks for the response! that's super helpful!

vestal minnow
# sacred sigil Do you know if the code for that is somewhere? It would be super useful to be ab...

Hmm... so the volume constraint that the example is using required some changes to the built-in solver and constraints. It needs to supports constraints for a dynamic number of entities, i.e. you can store the particle entities in a Vec, while in upstream bevy_xpbd the number is fixed, and you need to give the entity count through const generics.

But this shouldn't be an issue if you don't need a volume constraint or if you first "triangulate" (or in 3D, tetrahedralize) the soft body and use a separate area/volume constraint for each triangle/tetrahedron. This typically gives a better result anyway (like what blackedout01 later implements in the video series)

#

Which part of the code would you like? I could put the entire branch somewhere, but the important parts are probably the volume constraint and the actual soft body logic, would that be enough?

#

and yeah as I mentioned, that specific volume constraint won't really work in upstream bevy_xpbd

sacred sigil
sacred sigil
vestal minnow
#

@sacred sigil Here's the constraint and some logic for how my soft body is initialized and updated. To create a soft body with this, you'd just add SoftBody::default(), and it'd automatically initialize it based on the mesh vertices and indices.

Again, this has lots of issues, is 3D-only, for Bevy 0.11, requires some internal modifications, and isn't very commented so I'm not sure if even I understand what's going on in some places πŸ˜‚ This was mostly a throw-away thing I made for fun

#

Oh and this was just in bevy_xpbd itself, so crate refers to bevy_xpbd, and there are some math types like Scalar and Vector which are just type aliases (to support f32/f64 and 2d/3d with the same code)

sacred sigil
#

thank you!

frail robin
#

In 0.3.x I could dynamically disable or enable debug rending via PhysicsDebugConfig.
How can I do it now using gizmos?

vestal minnow
#

so something like

fn disable_physics_gizmos(mut config_store: ResMut<GizmoConfigStore>) {
    let mut config = config_store.config_mut::<PhysicsGizmos>().0;
    config.enabled = false;
}
frail robin
#

Ah, missed GizmoConfigStore, thanks!

vestal minnow
#

although that last system is missing fn and the variables aren't mut thonk

sacred sigil
cinder summit
#

Isn't that just what is now called DistanceJoint? πŸ€”

sacred sigil
#

I think so yeah

#

oops

sleek thicket
#

btw @vestal minnow what did you decide on raycast taking ray instead of origin + direction?

sleek thicket
#

ohh i didn't realize it's out πŸ˜‚

vestal minnow
#

Didn't do that yet, because it wouldn't work with f64 (e.g. ray casting far from origin) and I wasn't fully sure on the API yet

sleek thicket
#

how about
raycast(Ray3d...
raycast_from(origin, direction...

vestal minnow
#

I don't want to duplicate all ray casting and shape casting methods in SpatialQuery for that

sleek thicket
#

_from would just make ray and call raycast, is that still bad?

vestal minnow
#
  • cast_ray
  • cast_ray_from
  • cast_ray_predicate
  • cast_ray_predicate_from (name also doesn't make sense)
  • ray_hits
  • ray_hits_from
  • ray_hits_callback
  • ray_hits_callback_from
    and same for shape casting
#

yes, it's pretty bad

sleek thicket
#

yeah, it's pretty bad...

#

C#'s method overloading would really help there

vestal minnow
#

yeah

sleek thicket
#

but tbh it gets messy with 9 different ways of doing same thing anyway

slim ledge
#

Hi I get a panic with gizmos when using PhysicsDebugPlugin (no issue without it) in version 0.4.2:

assertion failed: value.is_normalized()
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::panicking::panic
   3: bevy_math::primitives::dim3::Direction3d::new_unchecked
             at /Users/[...]/bevy_math-0.13.0/src/primitives/dim3.rs:40:9
   4: <bevy_gizmos::gizmos::SphereBuilder<T> as core::ops::drop::Drop>::drop
             at /Users/[...]/bevy_gizmos-0.13.0/src/gizmos.rs:625:21
   5: core::ptr::drop_in_place<bevy_gizmos::gizmos::SphereBuilder<bevy_xpbd_3d::plugins::debug::configuration::PhysicsGizmos>>
             at /rustc/[...]/library/core/src/ptr/mod.rs:507:1
   6: bevy_xpbd_3d::plugins::debug::debug_render_axes
             at /Users/[...]/bevy_xpbd_3d-0.4.2/src/plugins/debug/mod.rs:206:14

Which is when drawing a spherical gizmo (in bevy_gizmos::gizmos::SphereBuilder::drop()), self.rotation * axis returns a non-normalized Vec3, which in turn means my rigid body has a weird Quat rotation.
What's happening here? πŸ€”

sleek thicket
#

you're drawing gizmo yourself?

slim ledge
slim ledge
vestal minnow
#

yeah it's a panic in debug mode

#

Direction2d::new_unchecked and Direction3d::new_unchecked have debug assertions for normalization

#

lots of successive rotations (or invalid quaternions) can sometimes cause the value to drift a bit

#

the normalization check should probably be made a bit more lenient

sleek thicket
#

did it happen because object was spinning too fast?

#

i think rather than making normalization check lenient, stuff like this could just make a warning about it

vestal minnow
#

We could also normalize in more places, but that's not ideal

sleek thicket
#

you know UV stretching heatmap view in blender? something like that for debugging

#

for whenever editor comes out

#

basically "if it's not normalized, log the amount" -> editor -> denormalization log

vestal minnow
sleek thicket
#

most of the time it's probably not necessary

#

i guess it could be an option

#

maybe a macro within direction for the check + what to do if it fails

#

or not macro but feature flag

vestal minnow
#

that way it'd always be normalized for stuff like this

sleek thicket
#

float drift can happen even without physics though

#

so something to catch it would probably be better long-term

vestal minnow
#

yeah

sleek thicket
#

panic when not normalized is already a bit too much, so until editor is there i think just subsequent check and report about the amount, error if it's clear that it's fubar

sleek thicket
slim ledge
#

and my game panics as soon as the physics simulation starts

sleek thicket
#

then it's probably a useful catch

#

but not to the point of panic, yeah

#

direction will need a second pass because of direction3A anyway, so it'll be a good time to do all that stuff

#

and hopefully rename to Dir3 ._. and compass + etc from LWIM

mossy flume
#

@vestal minnow not a huge deal but it seems like only impulses from continuous contacts are being relayed by the collision events, and momentary contacts like when an object with high restitution bounces off the ground don't report any impulse. additionally, there isn't a sudden spike in impulse when an object hits the ground hard. so it seems like maybe the impulse for the first frame of contact is lost for some reason? it looks like that video you posted a few days ago is showing the same thing. do you know how i could get this info out of bounces?

#

for these kinds of bounces, there is actually a contact event reported, but the impulse is just 0

#

i actually had this same problem with rapier so i feel like it might even be intentional, but i'd still wonder how to get around it

vestal minnow
# mossy flume <@545959292281552928> not a huge deal but it seems like only impulses from conti...

That's most likely because the impulse in collision events is only from the last substep. That's one of the caveats with the current implementation.

It should be possible to get the impulse at each individual substep using the Collisions resource in a system running in the substepping loop, here for example:

app.add_systems(
    SubstepSchedule,
    handle_impulses.after(SubstepSet::StoreImpulses),
);
#

I haven't tested if it works, but in theory I think it should

mossy flume
#

ahhh i see i wouldn't have thought of that, i'll try it!

vestal minnow
#

You'd query collisions like

fn handle_impulses(collisions: Res<Collisions>) {
    for collision in collisions.iter() {
        // ...
    }
}
mossy flume
#

ok perfect, that's actually what i'm doing now but i didn't have it in the substep schedule

#

thanks for the help

vestal minnow
#

np, let me know if it works

mossy flume
#

also, how often do substeps run?

#

well, what i'd like to do is accumulate the forces into a component for all the substeps of a full step

vestal minnow
#

SubstepCount times within one run of the PhysicsSchedule. The delta time is Time<Substeps>::delta_seconds

#

The total impulse should already be in the Contacts data returned for collisions though

mossy flume
#

no way man it's working!

#

thanks so much this is great

#

by the way, i have this system

.add_systems(
    PhysicsSchedule,
    reset_total_forces.ambiguous_with_all(),
)
#

i had to set it ambiguous with all or i'd get system conflict error

1 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- reset_total_forces and run_substep_schedule (in set Substeps)
    conflict on: bevy_ecs::world::World
#

is there a better solution than doing ambiguous with all? i don't think run_substep_schedule is publicly exposed so i don't know how to select it specifically

vestal minnow
#

You could do .after(PhysicsStepSet::Substeps)

#

or .before

mossy flume
#

ah k got it!

torn hedge
#

Hello everyone, currently trying to upgrade my project to the newest version of bevy and this crate.

i'm a bit confused on how to migrate my CollisionLayers to the reworked layers.

I'm using Qevy to create maps, and there i get a number based on what layers i click on, as seen in the image.
and i basically turn that into a Vec of L, L implements PhyiscsLayer:

let layers = props
    .get("collision_layers")
    .and_then(|cl| cl.parse::<u32>().ok())
    .map_or_else(Vec::new, |cl| {
        decode_flags(cl)
            .iter()
            .map(|flag| L::from_flag(*flag))
            .collect()
    });

let masks = props
    .get("collision_masks")
    .and_then(|cm| cm.parse::<u32>().ok())
    .map_or_else(Vec::new, |cm| {
        decode_flags(cm)
            .iter()
            .map(|flag| L::from_flag(*flag))
            .collect()
    });

if !layers.is_empty() || !masks.is_empty() {
    collider.insert(CollisionLayers::new(layers, masks));
}

the L::from_flag just returns the enum variant

that used to work, but now i get following error:

#
error[E0277]: the trait bound `std::vec::Vec<L>: PhysicsLayer` is not satisfied
   --> src\build.rs:229:62
    |
229 |                         collider.insert(CollisionLayers::new(layers, masks));
    |                                         -------------------- ^^^^^^ the trait `PhysicsLayer` is not implemented for `std::vec::Vec<L>`
    |                                         |
    |                                         required by a bound introduced by this call
    |
    = help: the trait `PhysicsLayer` is implemented for `&L`
    = note: required for `LayerMask` to implement `From<std::vec::Vec<L>>`
    = note: required for `std::vec::Vec<L>` to implement `Into<LayerMask>`
note: required by a bound in `CollisionLayers::new`
   --> crates\bevy_xpbd_3d\../../src\components\layers.rs:369:34
    |
369 |     pub fn new(memberships: impl Into<LayerMask>, filters: impl Into<LayerMask>) -> Self {
    |                                  ^^^^^^^^^^^^^^^ required by this bound in `CollisionLayers::new`

#

i can see in the docs that i can give it an array of PhysicsLayer, but it seems a Vec doesnt work?

sleek thicket
torn hedge
#

yeah probably, but imma be honest i don't understand the concept of bitmasks

sleek thicket
#

layermask has 32 bits, none is just 0
you checked the first 2 which is same as (1 << 0 | 1 << 1)

torn hedge
#

i kind of get the idea behind it, but can't quite wrap my head around when it comes to using it in practice

sleek thicket
#

each checkbox is basically a single bit out of i32

torn hedge
#

so, i just need to give it "3" for example, and xpbd would make out of that the two layers?

sleek thicket
#

yep

#

that's literally all that layermasks are

#

first bit is 1, second bit is 2, third bit is 4, fourth bit is 8...
layer 1 is 1, layer 2 is 2, layer 3 is 4, layer 4 is 8...

you basically perform simple bool operations x 32 bits
a | b is same as a || b for bool, if a or b is true, it returns true
a & b is same as a && b for bool, if a AND b is true, it returns true
a & !b is same as a && !b for bool, if both are true, it returns false

#

single layer operations are easy, and the collisionlayers wrapper is supposed to make the rest easy too

torn hedge
#

yeah awesome, thanks! figured it out now :)

sleek thicket
#

this thing needs a better documentation, it's supposed to be simple but it's strangely hard to explain despite everyone essentially using it daily

#

and you should be able to iterate through your stuff just based on 1 << n since it starts at 0 same as vec index

torn hedge
#

how can i toggle the debug plugin?
i used to be able to just

fn toggle_physics_debug(mut conf: ResMut<PhysicsDebugConfig>, input: Res<Input<KeyCode>>) {
    if input.just_pressed(KeyCode::F3) {
        conf.enabled = !conf.enabled;
    }
}

but i can't find anything to enable/disable it?

vestal minnow
#

this #1124043933886976171 message

torn hedge
#

ah, thanks!

maiden geode
#

How can I add custom "collision primitive"? A minercraft style voxel terrain, so collision lookup can be just a "is cell filled" check.

sleek thicket
#

you know A*?

maiden geode
#

I mean should I create a single entity for this, or multiple? AABB should span the whole terrain?

sleek thicket
#

colliders are overkill for this

maiden geode
sleek thicket
#

or you could just get a grid and check adjacent cells, which is ultra-fast in comparison πŸ€·β€β™‚οΈ

maiden geode
#

maybe we are talking about same thing, I've barely worked with xpbd, that grid still should be a collider, or do I need to hook into broad/narrow phase?

sleek thicket
#

you don't need a collider

#

look at how A* works

#

a built-in 2d/3d grid would be awesome though @vestal minnow

maiden geode
#

Sorry, I don't quite understand how A* can help in this case.

sleek thicket
#

your character's bounding box checks if it crossed over to the next cell, then updates player environment collider to exist in that cell if it's empty, or prevent moving in that direction

#

so when you're moving diagonally, you're essentially zig-zagging along the grid

#

if you ever played runescape, that's exactly how minecraft works too

#

since voxels are always on the grid, its' collision is entirely faked in a similar way to A*, and the bounding box on the player just needs to decide which cell player is in and to which one he's crossing over

maiden geode
#

That should work for general physics entity "roll a bouncy ball"? Thank you for explanation, I'll try to figure this out.

sleek thicket
#

considering how common tiles and voxels are, it's strange that grid isn't built-in into every physics engine by default tbh

vestal minnow
sleek thicket
#

for the grid most of the data in collider is pointless, it's always axis-aligned square/cube with uniform size

#

so if edge of bounding box on character moves from 0.9 to 1.1, it checks if grid cell at 1 is filled, and applies collision without thinking about cell's bounding box

#

i can't find what minecraft actually stores in voxels, block damage is most likely stored outside, so probably just the tile type, and tile durability is just matched against its' type? layer/sensor could also be done by block type.
so they don't need transform aside from grid itself, and might not even need to be entities as long as grid handles lighting and textures

#

i wonder if it's still relevant

blazing sluice
#

❀️ bevy_xpbd, grate crate mate.

bevy_framepace makes animation extremely jerky on my system, and bevy_xpbd seems to not like the FixedUpdate schedule. I can only get smooth animation by running the physics at full tilt, which is 1400fps at the moment, not ideal! Is this a known bug with FixedUpdate?

cinder summit
blazing sluice
#

Superb, thank you @cinder summit that's now running even smoother than my non-physics code. I was just trying .add_plugins(PhysicsPlugins::new(FixedUpdate)) which exhibits very strange behaviour.

dusty knot
#

... Why are you running at 1.4k fps?

blazing sluice
dusty knot
#

I mean, yes

blazing sluice
#

I want my game to be smooth and responsive, I'm just trying different stuff right now!

sleek thicket
#

and if you do, then something is probably wrong with your schedules

blazing sluice
#

Interesting, I'm not doing anything exotic with schedules. With default settings, I get what feels like 2 or 3 frames of input lag. With vsync disabled it's responsive.

#

I've not found a way of limiting FPS without compromising the experience, that's kinda what I'm asking about :D

torn hedge
#

hello everyone, i'm currently running into the issue that the game crashes when i spawn cubes on top of each other (not in each other, i make sure the distance between them is big enough) while having the debug on.

when i disable the debug before the cubes land on the ground, it works fine. i can also enable debug again after that, as showcased in the gif.
but if i have it enabled from the beginning, it seems to crash as soon as the cubes hit the ground/each other...

thats how i spawn them:

for i in 0..10 {
    // cube
    commands
        .spawn((
            Name::new(format!("Cube-{}", i)),
            PbrBundle {
                mesh: meshes.add(Mesh::from(Cuboid::from_size(Vec3::new(1.0, 1.0, 1.0)))),
                material: materials.add(Color::rgb_u8(124, 144, 255)),
                transform: Transform::from_xyz(0.0, ((i + i) + 20) as f32, 0.0),
                ..default()
            },
            RigidBody::Dynamic,
            Collider::cuboid(1.0, 1.0, 1.0),
            GravityScale(2.0),
            CollisionLayers::new(
                [MyPhysicsLayer::Player],
                [
                    MyPhysicsLayer::Ground,
                    MyPhysicsLayer::WallRunnable,
                    MyPhysicsLayer::Player,
                ],
            ),
        ));
}

and thats the error message i get:

thread 'Compute Task Pool (7)' panicked at .cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_math-0.13.0\src\primitives\dim3.rs:40:9:
assertion failed: value.is_normalized()
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_xpbd_3d::plugins::debug::debug_render_axes`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!

the assertion happens in the dim3.rs file of bevy_math, line 40:

pub fn new_unchecked(value: Vec3) -> Self {
    debug_assert!(value.is_normalized());

    Self(value)
}
sleek thicket
#

@torn hedge #1124043933886976171 message

trail sparrow
#

Hrm, I'm trying to update to bevy_xpbd and I'm running into some compilation errors:

error[E0277]: the trait bound `bevy::prelude::Gizmos<'w, 's, configuration::PhysicsGizmos>: bevy::prelude::GizmoPrimitive2d<bevy_math::primitives::Ellipse>` is not satisfied
   --> /Users/jpedrick/.cargo/git/checkouts/bevy_xpbd-87d8ac3552aaa63b/164f252/crates/bevy_xpbd_2d/../../src/plugins/debug/gizmos.rs:442:29
    |
441 |                         self.primitive_2d(
    |                              ------------ required by a bound introduced by this call
442 |                             ellipse.0,
    |                             ^^^^^^^^^ the trait `bevy::prelude::GizmoPrimitive2d<bevy_math::primitives::Ellipse>` is not implemented for `bevy::prelude::Gizmos<'w, 's, configuration::PhysicsGizmos>`
    |
    = help: the following other types implement trait `bevy::prelude::GizmoPrimitive2d<P>`:
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Direction2d>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Circle>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Ellipse>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Capsule2d>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Line2d>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Plane2d>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Segment2d>>
              <bevy::prelude::Gizmos<'w, 's, T> as bevy::prelude::GizmoPrimitive2d<bevy::prelude::Polyline2d<N>>>
            and 6 others

Some errors have detailed explanations: E0277, E0308, E0599.
For more information about an error, try `rustc --explain E0277`.

I'm using bevy from git main as of a couple of weeks ago...

vestal minnow
#

xpbd doesn't use Bevy's main branch currently

#

just 0.13

trail sparrow
#

Hm ok, so I'll just go and fix these myself

#

I can make a fork and PR to help track the API changes needed, so only one of us has to do the work

vestal minnow
trail sparrow
#

You mean two versions of bevy? I ran cargo tree -d and I only have one version(I think).

vestal minnow
#

bevy_xpbd uses 0.13 and you use main

trail sparrow
#

Ohh, this is probably the thing:

bevy_math v0.13.0
└── bevy_xpbd_2d v0.4.2 (https://github.com/Jondolf/bevy_xpbd.git#164f2523) (*)
torn hedge
vestal minnow
sleek thicket
#

degenerate is the proper term for it? i was just calling it denormalized πŸ₯²

#

degenerate body rotation somehow sounds really metal

vestal minnow
#

degenerate is basically just a math term for cursed things

#

like a triangle where all points are on the same line (collinear)

#

quaternions are generally expected to have a unit-length, not sure if unnormalized quats are strictly counted as degenerate in math though

#

I believe overall they aren't, but for rotations specifically they are

sleek thicket
trail sparrow
sleek thicket
#

"Due to floating point error, even safe operations like multiplying two quaternions (if both are normalised then the answer will be normalised already in theory) can have slight errors. It won't have a visible effect at first, but if you do something like rotate a character every frame the orientation quaternion can accumulate more errors until it starts to distort your model (it used to happen to the ogre camera, so renormalising was added to some ogre functions to correct it)."

vestal minnow
#

yep

sleek thicket
#

this is such a good description, it needs to be added to the doc for direction itself

vestal minnow
#

they're normalized every frame in the sim loop though

sleek thicket
#

what caused gizmo to fail assert then

vestal minnow
#

not normalized enough in that instance

#

the normalization doesn't happen at the end of the sim loop iirc, but at the start or middle

sleek thicket
#

on a side note, i had the same error thinking i forgot to normalize somewhere, and it turned out that it was because i multiplied 2 vectors expecting them to be unit, and one turned out to be 0

#

so adding the length to the warning/error would be super useful for these cases

vestal minnow
#

yeah

sleek thicket
#

and you probably need length anyway to give different warnings depending on how bad the situation is

#

on a side note, i went to check if ogre is still alive and found this

VET_INT_10_10_10_2_NORM support added
Ogre now supports normalized INT_10_10_10_2 as the vertex format. This packs 3 signed values with 10bit precision and a fourth 2bit value into 4 bytes – the size required by a single float.

If you are using normal-maps, you will notice how this format is perfect to store a tangent with parity, while only requiring 25% of storage compared to 4 floats.

Additionally, you can use it to store normals where storage requirements drop to 33% too.
In both cases the 10bit resolution is typically sufficient.

The format is natively supported by GLES3, GL3+, Vulkan and Metal meaning that you also save bandwidth and VRAM.
#

can't tell if glam does it by default

trail sparrow
trail sparrow
#

I'm having an issue where the capsule collider doesn't perfectly align with the collider mesh

#

I'm going back to the many_shapes example to try and see what's different

trail sparrow
#

Oh, it's simple. I just needed to call capsule.collider() instead of trying to make a new one that maps onto it.

mossy flume
#

is there a built-in way to change how strongly overlapping objects push against each other?

#

i'd like to be able to spawn 2 rigid bodies intersecting with each other and let them even themselves out on their own, but at the moment they fly away from each other way too fast

#

on the other hand if that's a behavior i should implement myself, is there a recommended way of adding a "custom collision solver" or something like that, or should i just write a system for it?

#

hrm maybe i actually need to think about the concept a little better, in real life a solid that is suddenly at 2x its normal resting density would definitely probably explode

sleek thicket
mossy flume
#

it's kinda in-between, i don't need the rigid body to deform but i want the repulsive force to scale based on penetration depth

#

regardless of whether i do the spawning-overlapping thing, i'll still need to implement this custom behavior for this type of body

sleek thicket
#

what's the actual purpose for this?

mossy flume
#

sph-ey fluids

sleek thicket
#

fluid sim?

mossy flume
#

i was thinking about making the bodies sensors instead of solid colliders and having my own system to handle these interactions

#

yeah

#

with a bit of custom behavior though

sleek thicket
#

mm.. xpbd is supposed to be good for that but not there yet

#

jondolf sent something about it before but i doubt i'll be able to find it

#

oh

vestal minnow
#

that's not SPH and doesn't have "soft" collision responses, but yeah that has some optimization things

mossy flume
#

good watch, thanks

#

on another note, is there a way to invert colliders?

#

making a quick bounding box around the screen with 4 half spaces but just being able to do a single inverted rectangle would be cool

vestal minnow
mossy flume
#

ahh ok makes sense, thanks for answering a silly question lol

vestal minnow
#

np!

trail sparrow
#

Would be nice if SpatialQueryFilter had something like add_excluded_entities

#

Or really, I think I wanna do something like:

fn some_sys( thing1s: Query<Entity, ...>, thing2s: Query<Entity, ...>, colliders: Query<...>){
   SpatialQueryFilter::default().with_entities((thing1s, thing2s));
}
sleek thicket
#

...?

#

why not from_excluded_entities?

#

or you mean add tuple to existing, instead of replacing it?

trail sparrow
#
    let inners : Vec<Entity> = force_ball_inner.iter().map(|(e,_c,_t)| ->Entity {e}).collect(); 
SpatialQueryFilter::default().with_excluded_entities(things.iter().chain([force_ball]).chain(inners.clone().into_iter())), 

#

I've got something like this

sleek thicket
#

what are you actually trying to accomplish with this?

trail sparrow
#

I'm doing a ray-cast and have a bunch of entities I need to exclude for it to work correctly

sleek thicket
#

and you can't use layers?

trail sparrow
#

Hm, maybe I should use a mask

sleek thicket
#

yeah, most of the time mask is just better

#

especially on raycasts.

#

it's even better if you don't use raycasts.

trail sparrow
#

I wonder if computationally a .with_entities function would be better for what I'm doing.

sleek thicket
#

probably not

trail sparrow
#

Well, this "force_ball" has a range, and within that range I want to test if walls are blocking the force.

#

So I can reduce the problem to a much smaller set of entities

sleek thicket
#

so, trigger range?

#

you're not making a clear explanation so it sounds like either a trigger or plain collision

trail sparrow
#

I'm not sure what you mean by a trigger.

#

It's kind of like a spell that gets blocked by things and also has a limited range

sleek thicket
#

so, a grenade-like behaviour? xD

trail sparrow
#

lol, yeah, roughly

sleek thicket
#

in that case it makes sense, what about the filter though

trail sparrow
#

Masks can definitely do what I need, but I'm just thinking the number of entities can be reduced by a lot since I use a Sensor to find everything in range to do the ray casting.

sleek thicket
#

why not shape intersections?

trail sparrow
#

You mean a shape-cast?

sleek thicket
#

no, shapecast is like raycast but shape

#

shape intersections is just intersection check

trail sparrow
#

I'm doing that

sleek thicket
#

in unity it was called overlap sphere/box

trail sparrow
#

But I want the effect to be blocked by walls

sleek thicket
#

it's a spatial query, not a collider/sensor

#

it finds all entities that match your filter, automatically sorting out everything out of range, then you can do your raycasts

trail sparrow
#

I see. Yeah, that actually is a nicer interface than the Sensor that I'm using

sleek thicket
#

your sensor is just cursed but i had something similar in unity

#

adding anything that enters to list

#

keeping it simple with overlap is less buggy and probably better performance anyway

#

so that's what i did after moving to bevy, i don't do it on every frame anyway

trail sparrow
#

I'm gonna look into bevy 0.13 ray casting too

#

Idk, it's not even that performance critical. I just have a situation where my game can become unplayable and I'm adding a "spell" that lets the player get the pieces unstuck

abstract tendon
#

i made a system that spawns a collider when click left mouse button, but sometimes it creates normal collider and sometimes it creates those strange colliders. is this normal?

vestal minnow
abstract tendon
#

huh so it should be fine if i use cuboid collider i guess

vestal minnow
#

(Rapier also does this fwiw)

sleek thicket
#

the non-uniform scaling was a #math-dev topic of the day, we could probably add this as another case of why does it even exist

abstract tendon
#

lmao maybe

#

but rn i will try to use xpbd raycast

sleek thicket
#

i'm trying to see how scaling is used in games that couldn't be baked for the mesh/animation, because i can't tell why it exists considering how many problems it brings

abstract tendon
#

i did the raycast and it works perfectly

#

but what exactly does this pink arrow mean?

vestal minnow
#

it's the surface normal at the hit point

abstract tendon
#

damn like i thought

#

hit.normal is the one that gives me the surface normal info right?

vestal minnow
#

yea

abstract tendon
#

nice

#

bro this is genius

#

i like it

vestal minnow
abstract tendon
#

yeap

abstract tendon
#

how can i get the mesh of a gltf/glb model so i can use it to create collider?

abstract tendon
#

so i managed to create collider for gltf model with this

commands.spawn((
        SceneBundle {
            scene: asset_server.load("models/shooting-range.glb#Scene0"),
            ..default()
        },
        AsyncSceneCollider::new(Some(ComputedCollider::TriMesh)),
        Name::new("Shooting Range"),
    ));
#

but its wrong

#

so uh, help me pls?

sleek thicket
abstract tendon
#

Yea

sleek thicket
#

wait nvm

#

you didn't even use the mesh here

abstract tendon
#

What

#

Oh yeah i used scene

abstract tendon
#

Because i kinda failed to use AsyncCollider with gltf

sleek thicket
#

ah it doesn't use gltf, i'll need to check it out tomorrow

abstract tendon
#

I used asynccollider with gltf before but now i dont remember it and i just tried it with asyncscenecollider

#

But your deleted message was right, no?

#

Maybe i messed up the model?

sleek thicket
#

i'm not sure, try loading a gltf sphere

#

i'll mess around with it tomorrow, i've been delaying it enough already πŸ˜‚

mossy flume
#

hey, sorry to bring this up again but i didn't end up getting enough information last time. i'm wanting to add a custom constraint for sph particles.

got a few questions about this. most importantly, how and when do constraints actually get added into the world? is this done every frame or once?

also, since my particles are technically not really rigid, should i still use a rigidbody component for them, or should i make a new component to represent them specifically? how would i define interactions between particles and normal rigidbodies?

sorry still kinda figuring out what i'm even doing! thanks!

#

or alternatively, should i run my sph stuff completely separately from xpbd and just have a light integration layer between them, instead of trying to build the whole sph thing within the xpbd framework?

sleek thicket
#

@mossy flume i couldn't remember what the end goal was and found that you were asking about minecraft-like game, are you trying to make a fluid sim in a voxel game?

mossy flume
#

something along those lines, yeah

#

just experimenting with ways of mixing the two

sleek thicket
#

that sounds like a bad idea then

mossy flume
#

lol wdym

sleek thicket
#

unless it's on a really small scale

#

or 2d

mossy flume
#

that's ok, i'm not really held up on whether it's a good idea or not, i'm just seeing what i can do

#

it is in 2d for now

sleek thicket
#

then look up how terraria did it, the source is essentially open

mossy flume
#

i thought terraria has a grid based fluid system

sleek thicket
#

xpbd is supposed to work well with fluids but you'd probably need to understand the entire physics engine to write it

#

and the whole xpbd started off from fluid sim from what i understand

mossy flume
#

it's ok i don't mind studying more about the engine, this is just something i'm interested in

#

really most importantly i'm just hoping to get more info about adding constraints

sleek thicket
#

then you'll have to wait until jondolf wakes up πŸ˜…

#

want a link to the stuff that bevy xpbd started from?

mossy flume
#

haha no worries, i'm not expecting a corporate support level service from bevy discord

#

hrm sure, wouldn't hurt!

sleek thicket
#
Johan Helsing Studio

In a sudden and ambitious outburst of not-invented-here syndrome combined with hype-train, I decided there weren't enough physics engines out there and it would be a good idea to write one myself using all the latest buzzwords. In this tutorial series, I'll explain step-by-step how to build an extended position-based dynamics (XPBD) rigid-body p...

mossy flume
#

also just gonna add a @vestal minnow here in case this gets lost under more msgs

sleek thicket
#

he'll probably read everything anyway

mossy flume
#

dang, maybe this is corporate level service then lol

sleek thicket
#

i mean, that's his crate so πŸ€·β€β™‚οΈ

mossy flume
#

haha ik ik, i still think it's impressive tbh

#

oh by the way, i'm having trouble with detecting sleeping bodies. tried adding a sleeping threshold, even set it very high and was able to observe bodies going to sleep midair, but the Sleeping component wasn't getting added. is there some config i need to set for that to work?

trail sparrow
#

I just logged all the components from a xpbd RigidBody πŸ‘€. I'm a bit curious about why all the fields are separate structs instead of grouping Current/Previous in structs

trail sparrow
#

@vestal minnow I think there's a bug in the spatial_query ray-casting logic for child transforms. Collisions for child entities work correctly, but it seems like for ray casting it's using &Transform in the local system coordinates.

trail sparrow
#

This function seems... wrong:

#

I'm still trying to understand the code, but it looks like you're treating scale, rotation and translation separately. Much easier to apply as a Mat4 containing all three.

fair fractal
#

for instance in substepping, the scale will never be changed so we only need to iterate on translation and rotation

#

the position and rotation components are better as their own components so that they can be adjusted and interpreted easier by the algorithms the physics engines use, like decomposing a quaternion to extract only the z axis of the rotation euler angles and then reconstructing a new quaternion just to update that one value introduces a lot of unneeded overhead, this would be especially prevailent in 2d physics simulations, or 3d simulations which have locked axes

vestal minnow
vestal minnow
# mossy flume hey, sorry to bring this up again but i didn't end up getting enough information...

sorry, this became long lol

how and when do constraints actually get added into the world?

This depends; joints are constraints that are just added by the user as components, and never cleared (unless you remove the component or entity).
Penetration constraints (which solve contacts) are stored in a resource, and are currently both initialized and solved in a special penetration_constraints system in SubstepSet::SolveConstraints.This could be split into e.g. prepare_contacts and solved by solve_constraints, but with the current architecture, it's more efficient to do them in the same system since it reduces the amount of iteration. This could change if we ever switch solvers or implement "simulation islands" though.

For custom constraints, you should typically solve them in the SubstepSchedule in SubstepSet::SolveUserConstraints. There, they won't have any system ordering conflicts. There isn't a specific place or time where "constraints get added into the world"; you can handle it however you want. But there's a built-in generic solve_constraint system that can handle some things for you in terms of actually solving constraints, and it currently expects constraints to be components. This is what solves e.g. joints.

There's a bit of docs on custom constraints here:
https://docs.rs/bevy_xpbd_2d/latest/bevy_xpbd_2d/constraints/index.html#custom-constraints

#

since my particles are technically not really rigid, should i still use a rigidbody component for them, or should i make a new component to represent them specifically? how would i define interactions between particles and normal rigidbodies?

I'm honestly not sure what the best approach would be, but if you want collisions against rigid bodies to work, you could still make the particles rigid bodies with colliders that have collision layers set up so that they don't collide against each other (since you probably want to handle fluid dynamics manually). But if you don't need collisions against rigid bodies, it could be a bit more efficient to have a custom Particle type and handle velocity integration (i.e. movement in this case) manually.

should i run my sph stuff completely separately from xpbd and just have a light integration layer between them, instead of trying to build the whole sph thing within the xpbd framework?

This is likely to be more efficient and flexible, and how built-in fluid simulation stuff would most likely work. I would expect it to also be more efficient to store particles outside the ECS in a custom data structure (maybe even do fluid sim on the GPU?)
But this can quickly get quite complex, so it might be easier to start within the existing physics framework

vestal minnow
#

PreviousPosition/PreviousRotation aren't meant to be very user-facing and probably aren't what you'd expect (they're the position/rotation from the previous substep, not frame)

vestal minnow
#

And physics doesn't really care about scale except for colliders

#

And there's a ton of other reasons for separate Position/Rotation too

trail sparrow
trail sparrow
vestal minnow
trail sparrow
#

I have a parent entity that I’m using as my world root and I’m letting bevy do the transformations internally

vestal minnow
trail sparrow
#

I’m just deciding if I need to rework my entity hierarchy or if the problem with child entity transformations in XPBD is easier to fix

#

I’ll see if I can made a small reproducible

vestal minnow
iron forge
#

||marking spoiler because i don't want this to distract the conversation||
||hi! i'm looking for some help about xpbd but idk if i should ask here or in github discussions page first ^^'||

||what's the process for applying central forces in a FixedUpdate system? namely, i just need to get a Vec3 of the current linear velocity and know how to mimic Godot's apply_torque(vec3) and apply_central_force(vec3).||
||i have more or less found how to apply forces despite not finding examples from the repo, as well as a tiny bit of math to figure out how to apply a central vec3 force, but i don't see anything for applying central torque||

trail sparrow
#

I’m using 0.4.2 from a git pull

#

I’m afk this second, but I’ll get the hash for you

#

I believe collisions were also incorrect. I’ll try to do a reproducible using many_shapes but make the box the child of an entity and the particles as root entities, then apply a transform to the box

vestal minnow
#

In a system you'd do

fn apply_forces(mut query: Query<&mut ExternalForce>) {
    for mut force in &mut query {
        force.apply_force(my_force);
    }
}
#

and similarly for torque

iron forge
#

thank you :3

#

last question for now: is this a central force relative to the center of the object, or is this from world position? i'm asking this because of the implication of the name ExternalForce
also is (linear|angular)Velocity a vec3? i've been having trouble with lsp autocompletion to discover lately x.x

vestal minnow
#

And yeah linear and angular velocity both use a Vec3 in 3D

sleek thicket
iron forge
#

@vestal minnow that's perfect! thank you :3

vestal minnow
#

I'm not sure if Bevy would add a GlobalTransform2d

sleek thicket
#

i'm just trying to understand what's going on from different perspectives

#

transform is a really uncomfortable clash between rendering, physics, ecs, and editing

vestal minnow
#

yep

sleek thicket
#

and nobody's making their position clear

vestal minnow
#

I'm not sure if people have really formed strong opinions on the exact approach yet, so it's kinda hard to have a clear position

#

There's also the thing where having a separate visual transform and physics transform could be useful for visual interpolation

#

Like you might want to update the visual position several times in between physics frames

#

without affecting the actual simulation

sleek thicket
#

yeah, that's what i'd imagine affine would be used for

#

unity has a dropdown menu for static/dynamic next to transform, so i think it would be simple enough for users once editor is out

vestal minnow
#

We might handle static bodies with a separate Static component that is used by both rendering and physics if the PR gets merged

#

GUI-wise it could be handled similar to Unity though

sleek thicket
#

Many systems in Unity can precompute information about static GameObjects in the Editor. Because the GameObjects do not move, the results of these calculations are still valid at runtime. This means that Unity can save on runtime calculations, and potentially improve performance.
so basically it does what the whole thing in #math-dev started with

vestal minnow
#

yea, it'd allow some (slight) optimizations on the physics side too since you can skip iterating over static bodies in some cases

#

I've been thinking of adding a Static component anyway

trail sparrow
vestal minnow
#

Transform2d is planned and relatively likely to be added, but mainly as an API thing. Rendering would probably remain using 3D types.

#

for now at least

#

same for TransformF64, it'd be for e.g. physics, but be converted to f32 for rendering

trail sparrow
#

Shouldn't be hard to convert almost everything to Vec4D/Mat4D... Instead of using the glam type just use a type alias

#

Then convert at the interface between OpenGL and bevy

vestal minnow
trail sparrow
sleek thicket
#

@trail sparrow did you see #math-dev ?

trail sparrow
sleek thicket
#

#math-dev message i should've sent the pin instead

trail sparrow
trail sparrow
trail sparrow
#

Anyone else have the ray_caster example crashing in debug?

#

Looks like the AngularVelocity is causing the ray vector fail a debug_assert!(ray.is_normalized()) check

#

@vestal minnow so toying with the ray_caster example is looks like the colliders don't apply the parent scaling

abstract tendon
#
commands.spawn((
        AsyncCollider(ComputedCollider::ConvexHull),
        PbrBundle {
            mesh: asset_server.load("models/shooting-range.glb#Scene0"),
            ..default()
        },
        Name::new("Shooting Range"),
    ));
#

im using this code to create collider from gltf mesh

#

but it doesnt work

#

whats wrong? how can i fix it?

trail sparrow
#

What doesn't work?

abstract tendon
#

it doesnt generate a collider

vestal minnow
#

It should be an AsyncSceneCollider if you're loading a scene

abstract tendon
#

yeah i tried asyncscenecollider yesterday and it looked like this

#

i guess im not properly scaling in blender

vestal minnow
#

Have you tried options other than ConvexHull? And yeah I think you need to make sure you have applied scale with Ctrl+A -> Apply scale (or something like that)

abstract tendon
#

yeah i tried trimesh too

abstract tendon
#

default objects worked perfectly

#

my scaling is wrong

#

and yeah

#

Ctrl + A -> All Transforms

#

this is the fix

#

so with raycast, in console it says "Hit entity 10v1"

#

is there any way to give a name to this collider?

#

wait, no i dont need to give a name, blender mesh name is the collider name

#

hit.entity is giving me the entity

#

but i need the name

vestal minnow
# abstract tendon but i need the name

I think Bevy might add Name components for the meshes spawned based on the glTF scene, maybe you can query for it based on the entity?

fn my_system(query: Query<&Name>) {
    // ...
    // yay I have the ray hits
    if let Ok(name) = query.get(hit.entity) {
        // do something with the name
    }
}
#

not 100% sure but I think Bevy adds names

abstract tendon
#

it does have a name

#

lemme show you

#

this is the name

#

but raycast is giving me the entity 10v1

mossy flume
# vestal minnow sorry, this became long lol > how and when do constraints actually get added in...

thank you for the detailed reply, this is extremely useful.

i'll try rigidbody with collision filter mask first, and if that's not performing well enough i'll try writing a separate implementation. my only concern in the latter case would be about duplicating effort on making spatial partitioning code which xpbd has built in. does xpbd expose any utilities for this?

i'll report back later : )

vestal minnow
#

I imagine a spatial grid could maybe be better for fluid sim

vestal minnow
#

Thanks πŸ˜„ I'm glad it works!

trail sparrow
#

@vestal minnow I tried all manner of ways to reproduce the problem I'm having and haven't been able to do it. At this point I think it's a bug of my own creation. In the process I played around with the ray caster example and did this:

#

Not sure if you'd be interested in adding that, as I use the SpatialQuery as a system argument here

sleek thicket
#

cast_ray doesn't have a parent so it makes sense that it's not buggy
what about ray_caster though? @trail sparrow

trail sparrow
#

In my game I'm not using a RayCaster component

trail sparrow
#

I had reworked my entity hierarchy because rotations of my map caused the framerate to drop when I was rotating each entity

iron forge
#

how do i recognize players apart from trerrain ground or self-intersections?

sleek thicket
deep ingot
#

by chance do Collision events get swallowed by higher-level entities in the Bevy entity hierarchy before propagating to lower levels?

drifting marsh
#

these docs are a bit confusing. "distance travelled" would imply the orange line but "distance between origin and point of intersection" implies the blue line

vestal minnow
vestal minnow
#

(I added that image to illustrate the issue if that's fine)

drifting marsh
#

yeah, thanks

lavish orbit
#

was wondering how you guys would recommend creating a "box select" for an RTS game, I basically want to cast a bunch of rays in a rectangle downward to select my units (which all have colliders), just wondering what would be a good way to do this

cinder summit
vestal minnow
#

shape_intersections will be more accurate since it considers the actual shapes and not just the bounding boxes

lavish orbit
#

awesome, thanks!

cinder summit
vestal minnow
#

yeah, true

iron forge
sleek thicket
#

No you make it yourself, any component

#

I use an enum to sort it out though

vestal minnow
# iron forge does that happen to be available in xpbd's collision events? i forgot to ask

the entities are available, but you need to check if they have Player/Ground/Whatever components yourself if you want to distinguish them

fn my_system(mut collisions: EventReader<Collision>, player_query: Query<&Player>) {
    for collision in collisions.read() {
        // Check if either entity is the player
        let is_player = player_query.contains(collision.entity1)
            || player_query.contains(collision.entity2);
        // Do whatever, maybe check if the other entity is also terrain
}
#

if you don't need contact data (contact points and normals) and just want to know when players are colliding with e.g. the ground, you could also query for the CollidingEntities of players directly, and check if they include entities with the Ground component

iron forge
#

so i can just query in the signature and all should work?

vestal minnow
#

yeah

iron forge
#

nice! thank you :3

deep ingot
#

any tips for debugging a faulty sensor? i already logged the globaltransforms of the entities involved and can't see any reason that a collision wouldn't fire.

sleek thicket
#

if layers are fine and one of the colliders has (dynamic i think?) rigidbody then it should just work

deep ingot
# sleek thicket if layers are fine and one of the colliders has (dynamic i think?) rigidbody the...

I'm setting it up like this:

.with_children(|parent| {
    parent.spawn((
        Name::new("Door Collider"),
        Collider::cylinder(player::HEIGHT / 2., player::RADIUS * 5.),
        CollisionLayers::new([CollisionLayer::Sensor], [CollisionLayer::Player]),
        Sensor,
    ));
});

The thing I find weird is that I only get collisions on Sensor 32, which is a child of the "house entity" and not Sensor 34 which is a child of the "door entity". The "door'" entity itself is a child entity of "house". Does the collision detection care about the entity hierarchy at all?

sleek thicket
#

i guess it might've turned into compound collider but i have no idea what the rules are for xpbd

#

in unity it called parent by default but you could easily access the actual collider causing the hit (from player's perspective)

#

if it works fine if you unparent it then it's probably similar to that

#

you generally don't want to make children unless you really need them for something specific anyway, it causes a lot of bugs even outside of physics

vestal minnow
vestal minnow
sleek thicket
#

i'm not even sure if that's good or not, it's good for me but how easy is it to get parent if you just want to put the damage script on parent to be responsible for the whole body?

#

actually no, considering how many times i've answered how to get the collider hit and not the parent, it's definitely better

vestal minnow
#

you can get the root rigid body of a collider with the ColliderParent component if that's what you mean

sleek thicket
#

alright, i'll try to make an example for generic modern military shooter for loading model + animations + colliders + getting parent... ... ...eventually...

#

or actually, maybe i should wait for that gltf collider extension
both ways are useful to show πŸ€·β€β™‚οΈ

drifting marsh
#

I think these are all incorrect. I've only tested point1 and normal1 but they don't appear to be in the local space of the collider. (didn't meant to include time_of_impact in the screenshot)

lavish orbit
# vestal minnow Yeah if you just want the entities in some area, you can use [`shape_intersectio...

so, maybe this isnt the place to ask, but how would you recommend going from two mouse positions (top left and bottom right of the dragged box) to the required scale for the collider with the shape cast? I found camera::viewport_to_world, but this is on the near plane. maybe I could then use the origin of the rays that gives me, and do some calculation with the camera's fov, to create a cone maybe?

sleek thicket
#

viewport_to_world is just point+dir of cursor your screen in the world, if you raycast using it you will hit the exact point in world, or with ray.intersect_plane() you get it at the intersection

vestal minnow
#

I'll try to find that

drifting marsh
#

I found this which has the descriptions reversed for point1/point2 and normal1/normal2

#

The issue I'm talking about though is that they aren't in local space but world space

vestal minnow
#

So the result being in world-space is interesting

drifting marsh
#

ok, I'm getting strange results

#

point2 appears to be in local space but point1 isn't

vestal minnow
#

huh thonk

drifting marsh
#

and if I'm not reading the values wrong, both normals appear to be world space

vestal minnow
#

it's just mapped from Parry values like this

ShapeHitData {
    entity: query_pipeline.entity_from_index(entity_index),
    time_of_impact: hit.toi,
    point1: hit.witness1.into(),
    point2: hit.witness2.into(),
    normal1: hit.normal1.into(),
    normal2: hit.normal2.into(),
}

I'm not doing any weird transformations afaik

#

and Parry says they all should be local

#

but I'm also getting world-space normals

#

or normal2 might be local-space?

#

the one on the cast shape

lavish orbit
sleek thicket
lavish orbit
#

3d

sleek thicket
#

then... hmm...

vestal minnow
sleek thicket
#

projecting camera's frustum as a shape to do that

#

i can't even find if it's an existing shape

cinder summit
#

Because there isn't one :')

#

Making a cuboid from the corners in world position and padding them by some arbitrary extra height should be good enogh tho

vestal minnow
cinder summit
#

It would need to be a collider for shape_intersections tho

vestal minnow
#

yeah

#

but maybe you can create some collider based on the frustum

#

like a convex hull from corners

#

although that might be a pain to create from the frustum's half-spaces, idk how exactly the API for them works

sleek thicket
vestal minnow
#

no one has done it yet

#

we also need a HalfSpace primitive

#

useful as a collider too

cinder summit
sleek thicket
#

that's like saying trapezoid isn't a primitive

lavish orbit
#

sooo, what I understand about this is that there isnt a primitive shape for the camera frustum. which means its harder to create the collider for it?

vestal minnow
#

we could have more frusta like a frustum with a regular polygon base, but a view frustum might be a bit rendering-specific and not that primitive-y

cinder summit
sleek thicket
#

ah

#

so the data needed for rendering isn't the same as what would've been in a prim?

cinder summit
sleek thicket
#

nah that depends on FoV

#

and angle. which gets really skewered in some cases

#

it'd get really weird if it's not ortho

lavish orbit
#

I was thinking of using a cuboid, and dynamically scaling it based on angle and FoV, but I just hope it looks right

vestal minnow
sleek thicket
#

primitive

vestal minnow
#

oh I misread lmao

sleek thicket
#

prism would be a neat prim shape though

cinder summit
#

A prism is just an extruded 2D shape right?

vestal minnow
#

Yea, and there are also some weirder variants of it like twisted or truncated prisms

cinder summit
vestal minnow
#

extruding a polyline might be cursed

cinder summit
#

Not as cursed as this one:
type Cylinder3d = Extruded<Circle>

#

The SDF code is actually the same for extruded and cylinders tho thonk

vestal minnow
# cinder summit Upstreaming <https://github.com/NiseVoid/bevy_prototype_sdf/blob/main/src/dim3.r...

Okay so we could pretty easily do

  • Circle
  • Rectangle
  • Regular polygon (becomes a regular prism)

and maybe do

  • Ellipse (some weird scaled cylinder?)
  • Triangle (just a convex polyhedron probably)
  • Plane (should this extrude upwards or along normal?)

and these could be quite cursed

  • Lines, line segments
  • Polygon (I guess run convex decomp or something?)
  • Capsule2d (a cuboid with the ends rounded but a flat top and bottom)
#

You probably could implement support mapping and have proper collision detection for shapes like the extruded ellipse and extruded 2D capsule, but they might be weird shapes to have support for

cinder summit
#

Enter extruded arc thonk

#

Gotta have those concave colliders to ruin your day

vestal minnow
#

Gotta get those SDF collisions into bevy_peck

#

Yeah we could just use SDFs for all the weirder extruded shapes thonk

#

then also add support for revolving shapes because why not

lavish orbit
#

so this is my code now:

let screen_ray_start = camera.viewport_to_world(camera_transform, select_box.start);
                let screen_ray_end = camera.viewport_to_world(camera_transform, select_box.end);

                if let (Some(ray_start), Some(ray_end)) = (screen_ray_start, screen_ray_end) {
                    let start = ray_start.origin;
                    let end = ray_end.origin;

                    let x = (start * 100.0).x;
                    let y = (start * 100.0).y;

                    let end_x = (end * 100.0).x;
                    let end_y = (end * 100.0).y;

                    let hits = spatial_query.shape_intersections(
                        &Collider::cuboid((x - end_x).abs(), (y - end_y).abs(), 100.0),
                        // what to set position to?
                        camera_trans.rotation,
                        SpatialQueryFilter::from_mask(GameLayer::Unit),
                    );
#

but I dont know what the shape position should be

vestal minnow
#

assuming you want it to span from x to end_x and y to end_y

lavish orbit
#

it always gets centered on the camera, im probably just too tired for this rn

sleek thicket
#

https://docs.unity3d.com/Packages/[email protected]/manual/workflow-create-predefined.html
https://docs.unity3d.com/Packages/[email protected]/manual/shape-tool.html
i'm guessing there will be a similar tool in the future for the editor, so it might be useful to see how they did it
especially cylinder/pipe/arch because you can set number of sides to 3 to make them triangular
and with arch it's possible to create prism/"pipes"/cylinders so other shapes feel a bit redundant

so, a hollow n-gon with angle would probably make a good primitive

vestal minnow
sleek thicket
#

yep, decomposition if inner radius isn't 0

#

large angle would need it too anyway

vestal minnow
#

but yeah we'll probably add a 2D ring shape, a tube would be an extruded version of that

#

and we could just add a Tube primitive too I guess

sleek thicket
#

it should probably be possible to switch between similar shapes (by the editor itself)

#

cylinder, pipe/tube(just a hollow cylinder), arc(h) (just a pipe with angle cut), and.. what do you call a cylinder with angle cut? pizza?
n-gon/prism would fit better with 3d mesh though

...ok i'm starting to see why not-primitive-enough is a good argument...

zinc talon
#

This might be answered somewhere, but what's the story on determinism? Looks like glam supports it but how much thought has been given to it for xpbd?

sleek thicket
#

theoretically should be possible (compared to nv physx)

vestal minnow
#

yeah it's not fully deterministic yet, and it's a bit unclear where the source of indeterminism is, but I'm reasonably confident it should be possible

sleek thicket
#

we just need someone with enough determination to come around to fix it πŸ₯²

zinc talon
#

determinism determination?

sleek thicket
#

determination to make it deterministic

zinc talon
#

determination to determine what's not deterministic πŸ’€

sleek thicket
#

yep

#

determination to determine what's causing it not to be deterministic.

zinc talon
#

Are there existing non-determinism repro cases out there? Maybe in an issue?

#

What platform/hardware/etc.