Advice for location-based hitbox?

Post Reply
Jonathan
Posts: 36
Joined: Sun Feb 10, 2013 6:52 pm

Advice for location-based hitbox?

Post by Jonathan »

Currently, in order to do location-based damage to objects in my game (whether it be a headshot for a person, or blowing up a rear engine, or disabling a gun turret), I've been creating an extra rigidbody for each location-based damage zone. I use a 6DOF constraint with all the axis locked in order to simulate the location being attached to the main object.

I've recently become aware that even, what I thought to be, "locked constraints" will act springy if stressed enough. I am now thinking that maybe my method of doing location-based damage is not the right one? Is there something obvious that I have overlooked to achieve this effect? If having separate bodies and constraints is the best way to do this, then I guess the timing of Bullet's new 2.82 release is perfect for me, because Featherstone seems like it might be a good improvement for my situation? (I haven't had a chance to upgrade my game's Bullet version to the new one... but soon! :) )

This is a fairly common thing in games (at least the headshot hitbox part of it), so I'm sure you guys know of some smart ways to go about implementing this. I'd appreciate any advice, thanks!
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: Advice for location-based hitbox?

Post by c6burns »

Why not have the hitbox rigid body be kinematic, and just keep it in the correct position every frame?
Jonathan
Posts: 36
Joined: Sun Feb 10, 2013 6:52 pm

Re: Advice for location-based hitbox?

Post by Jonathan »

c6burns wrote:Why not have the hitbox rigid body be kinematic, and just keep it in the correct position every frame?
Hmm, that might be the solution for "headshot hitbox"... but in the case of a rear engine on a spaceship. If ship1 collided with ship2's engine, obviously I'd want the physics result to be realistic (probably send ship2 into a spin). Kinematic doesn't receive physics, but I guess I could have a kinematic trigger and set the position of that every frame. Is that what most people would do?
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: Advice for location-based hitbox?

Post by c6burns »

In terms of trigger zones, that's what I do, but I don't do anything exactly like what you are doing in my projects. You could also look at compound shapes, since you aren't actually using constraints except to keep bodies locked together.
Jonathan
Posts: 36
Joined: Sun Feb 10, 2013 6:52 pm

Re: Advice for location-based hitbox?

Post by Jonathan »

c6burns wrote:In terms of trigger zones, that's what I do, but I don't do anything exactly like what you are doing in my projects. You could also look at compound shapes, since you aren't actually using constraints except to keep bodies locked together.
I thought of compound shapes too, but upon further reflection, I was confused on how to determine which sub-collider was hitting a contact manifold. Is there a way to do that in Bullet that I'm missing? Basically, I know you can give each btRigidBody a user pointer, but I'm assuming if you give a btCollisionShape a user pointer, that would become shared across all users of that shape, and be ambiguous to determine which btRigidBody it belongs to... correct?
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: Advice for location-based hitbox?

Post by c6burns »

I would deal with this problem as 2 separate issues. One is determining if a special zone has been hit, and the other is appropriate physics. The compound shape is just getting rid of your constraints and thus your solver issues. The special kinematic trigger (which you would likely flag with btCollisionObject::CF_NO_CONTACT_RESPONSE) is allowing you to easily figure out what part of a game object is taking damage.

Anyway this is just how I approached similar issues. Perhaps someone else has a more elegant solution.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Advice for location-based hitbox?

Post by Erwin Coumans »

You can get access to which child shape is involved in a collision (or ray cast). For a collision, you can get the contact added callback to get to this information (see gContactAddedCallback in the Bullet/Demos/ConvexDecompositionDemo).
Jonathan
Posts: 36
Joined: Sun Feb 10, 2013 6:52 pm

Re: Advice for location-based hitbox?

Post by Jonathan »

Erwin Coumans wrote:You can get access to which child shape is involved in a collision (or ray cast). For a collision, you can get the contact added callback to get to this information (see gContactAddedCallback in the Bullet/Demos/ConvexDecompositionDemo).
Edit: My only main question right now is, I was under the impression gContactAddedCallback was called too frequently to be used with game logic. The wiki says:
Be careful when using contact callbacks. They might be called too frequent for your purpose.

gContactAddedCallback:
This is called whenever a contact is added. From here, you can modify some properties [eg friction] of the contact point.

I am currently iterating over all contact manifolds in the suggested loop and dispatching collision events like that, are you saying (from a performance standpoint) it's acceptable to just use gContactAddedCallback instead of the contact manifold loop?


Ah thank you! It is good to know this is a possibility. In the past, you have said it's best to share one instance of btCollisionShape among duplicate rigid bodies. I could imagine setting the shape's user pointer to store information (like an ID) that describes what part it is.

For example,
btCompoundShape is composed of:
-btBoxShape (user pointer info: Enum::SPACESHIP::HULL)
-btBoxShape (user pointer info: Enum::SPACESHIP::ENGINE)
-btBoxShape (user pointer info: Enum::SPACESHIP::SHIELD_GENERATOR)

And then in the gContactAddedCallback, I further dispatch information about the specific collider hit. Hopefully something like that will work. :)

Should this ever do anything besides return true?

Code: Select all

bool MyCompoundChildShapeCallback(const btCollisionShape* pShape0, const btCollisionShape* pShape1)
{
        return true;
}
Thank you for your time!
Post Reply