Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider allowing contacts between static/kinematic bodies. #15

Closed
sebcrozet opened this issue Sep 23, 2020 · 10 comments · Fixed by #44
Closed

Consider allowing contacts between static/kinematic bodies. #15

sebcrozet opened this issue Sep 23, 2020 · 10 comments · Fixed by #44
Labels
enhancement New feature or request user experience Potential user-experience improvements

Comments

@sebcrozet
Copy link
Member

Currently, the detection of collisions between two static bodies, two kinematic bodies, or one static and one kinematic bodies, will be ignored (the contact points won't even be computed).

It may be useful to have a way to tell Rapier that we do want some contacts between static/kinematic bodies to be computed by the narrow-phase, but ignored by the constraints solver. Maybe that could be useful for character controllers?

I would like to open the discussion on whether this can be useful and why. Please comment or add a 👍 bellow if you are interested in this feature, or 👎 if you think this is completely useless.

@sebcrozet sebcrozet added enhancement New feature or request user experience Potential user-experience improvements need community feedback Feedbacks are needed from the community before implementing a solution labels Sep 23, 2020
@Ralith
Copy link
Contributor

Ralith commented Sep 23, 2020

The character controller use case depends on whether it makes sense for a character controller to be a kinematic body rather than a sensor or a procedure that runs queries each step and doesn't actually exist in the physics world per se. A kinematic body makes it easy to exert forces on the environment, which is useful in theory, but seems liable to produce instability in practice.

@ConnorBP
Copy link

Kinematic and static don't generate collision events? Aw man i'm trying to make a character controller right now and rapier just keeps surprising me with very ..... unique design decisions. I can't seem to find any examples of a good kinematic controller implementation anywhere. Was originally going to use dynamic for my controller, but that proved to be majorly jank with the tools I could find available to me.

How then if not with collision detection should i stop my controller from falling through floors and walking through walls? I assume the standard ray/box cast method should be used?

If anyone knows of any good examples for either dynamic or kinematic character controllers in bevy I would love to see them :D for now i guess it is time to put on my linear algebra hat

@stephanemagnenat
Copy link

stephanemagnenat commented Sep 30, 2020

For me for Cand.li that would be extremely useful. Currently I'm using Planck-JS that ignores these contacts as well and it is a big limitation as it prevents the detection of a platform reaching the end of a gap for example.

So indeed for my specific use case it would be helpful that such contacts are detected but not used in the constraint solver.

Also theoretically, personally I would find it nice that the contact detection, which is a geometry operation, is independent of the actual physics. Of course I can imagine that for performance reason some pruning should rather be done early, so it might be best to have it as a global option, or per body or collider/sensor.

@sebcrozet
Copy link
Member Author

@ConnorBP

Kinematic and static don't generate collision events? Aw man I'm trying to make a character controller right now and rapier just keeps surprising me with very ..... unique design decisions.

Kinematic/static contacts are ignored by most physics engines out there. Keep in mind that what you call design decisions are either missing features, or decisions that are still open to discussion (including what this issue is about). So if you find something missing or some design decisions bothering you, don't hesitate to open issues to see what we can do about it.

How then if not with collision detection should i stop my controller from falling through floors and walking through walls? I assume the standard ray/box cast method should be used?

This is typically handled by ray/box-casting yes. Box casting is not possible yet with Rapier and ray-casting is being worked on in the raycast branch.

@sebcrozet
Copy link
Member Author

@stephanemagnenat

Currently I'm using Planck-JS that ignores these contacts as well and it is a big limitation as it prevents the detection of a platform reaching the end of a gap for example.

I think this is generally done using ray-casting or convex-casting (which are both not supported by Rapier yet but are being worked on). Though I agree that doing this with contact events may be more convenient because it allows reusing some contact event handling code you may already have to deal with these platforms too.

Also theoretically, personally I would find it nice that the contact detection, which is a geometry operation, is independent of the actual physics.

Within a single timestep (one call to physics_pipeline.step()), collision detection and force computation are already independent. Right now PhysicsPipeline executes both stages automatically but we could probably design it differently to allow executing only the geometry part, and with a second method call the physics part for example. This will become less feasible when we will support CCD (continuous collision detection) though because this introduces a coupling between physics (that governs motion) and collision detection (that uses these motions to compute times of collision exactly) but we are not there yet.

Two things are certain though:

  • We are currently working on the definition of another pipeline called the QueryPipeline which allows to perform efficiently one-time geometric queries (ray-casting, convex-casting, box queries, etc.) on the whole collider set. This means for example that one could use the PhysicsPipeline for contact determination and physics integration, alongside the QueryPipeline for individual geometric queries.
  • Further in the future we will add another pipeline that performs only collision-detection (but no physics whatsoever).

Anyways, I think that this issues about wanting some contacts ignored by the solver is closely related to #24, as well as (to a lesser extent #3 and #2). So maybe digging into #24 further will actually cover this issue.

@superdump
Copy link

I gave this a thumbs up as I was expecting to get contact events for implementing a character controller using a kinematic body with a collider on it and then having various static and dynamic bodies in the world, also with colliders. That said, I don't know if this is necessarily a good way to implement a character controller. I'd probably be happy to be able to build something based on ray-casting or saying something like "this bounding box is going to move linearly from here to here, give me the closest hit if any" and then I suppose one may need to iterate that.

However, if I take a step back, I mostly just want to be able to control the feel of the input controls' interactions with the character. I've seen discussion of attack, decay, sustain, release envelopes applied to animations and regardless of the feel I'm looking for, I expect that I have to do this through controlling a kinematic body if I want the physics engine to simulate the interactions of that body with the other simulated objects. At this point I'd be happy if rapier took care of dealing with object penetration so that I can bump up against walls or 'walk' along the ground, jump on top of things, push dynamic objects, etc rather than me having to reimplement that for no good reason.

I'm undecided and am open for input for ways for kinematic bodies to cooperate with the physics engine. #24 sounds like a good way to open up for flexibility to implement handling for gaps, stairs, etc.

@superdump
Copy link

Searching around for more input I found this long and detailed discourse as part of PhysX: https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/CharacterControllers.html

It suggests that the kinematic body controller do continuous collision detection (is this what you mean by a box query? I’m imagining that one projects/extrudes the bounding box of the geometry along its trajectory and then tries to see if that intersects with anything, maybe done differently or more completely with dynamic bodies.)

Also it notes that the kinematic body controller should probably specifically handle the interaction on collision with dynamic bodies because a cuboid or capsule collider will tend to apply force not through the centre of mass and so cause the body to rotate which is often not what was intended (e.g. pushing a box.) This sounds like more support for a combination of this issue and #24 - both that the collision event is triggered and that there is a way to override a default dynamic body collision to provide an alternative interaction that makes more sense for what was intended. What do you think of this @sebcrozet ?

@Ralith
Copy link
Contributor

Ralith commented Oct 4, 2020

For traditional uses of kinematic bodies which don't need any contact info, could this impair performance?

@sebcrozet sebcrozet removed the need community feedback Feedbacks are needed from the community before implementing a solution label Oct 27, 2020
ryo33 pushed a commit to ryo33/rapier that referenced this issue Nov 15, 2020
@mrchantey
Copy link

mrchantey commented Sep 2, 2023

great to see this is merged in! Is there an example available for detecting collision events between non-dynamic rigidbodies? ie something like Unity's OnTriggerEnter()

I've been playing around with the physics hooks but maybe have misinterpreted how they are supposed to be used:

My attempt
fn main(){
  App::new()
    .add_plugins(DefaultPlugins)
    .add_plugins(RapierPhysicsPlugin::<Hooks>::default())
    .add_systems(Startup, spawn)
    .add_systems(Update, check)
    .run();
}

#[derive(SystemParam)]
struct Hooks;

impl BevyPhysicsHooks for Hooks {
  fn filter_intersection_pair(&self, _context: PairFilterContextView) -> bool { 
    true 
  }
}

fn spawn(mut commands: Commands) {
  commands.spawn((
    SpatialBundle::default(),
    RigidBody::Fixed, //naturally it triggers if this is changed to Dynamic
    Collider::ball(1.),
    ActiveEvents::COLLISION_EVENTS,
    ActiveHooks::FILTER_INTERSECTION_PAIR,
  ));
  commands.spawn((
    SpatialBundle::default(),
    RigidBody::Fixed,
    Collider::ball(1.),
  ));
}

fn check(mut reader: EventReader<CollisionEvent>) {
  for event in reader.iter() {
    match event {
      CollisionEvent::Started(_, _, _) => {
        println!("start collision");
      }
      _=>{}
    }
}

Edit

Ok it looks like the solution i was after can be achieved using RapierContext

fn check(rapier_context: Res<RapierContext>, query: Query<Entity>) {
  for entity in query.iter() {
    for intersection in rapier_context.intersections_with(entity) {
      println!("bang! {:?}", intersection);
    }
  }
}

It would still be nice to have an event-based way to do this, I guess at the moment the best way is to hand-roll our own?

@aarthificial
Copy link

For people who (like me) may stumble upon this issue in the future: in newer versions ActiveCollisionTypes can be used to enable contacts between static/kinematic bodies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request user experience Potential user-experience improvements
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants