Sign in to follow this  
IceCave

How to handle a collision in a physics library and OOP?

Recommended Posts

Simple question, I am utilizing a general physics library in my game or at least I want to.

(I don't actually want physics in my game but simple fast raycasting and collision detection which doesn't seem to be available in a library without all the other physics stuff as well.)

Now the basic problem is that those libraries available don't know MY game (of course) so the only feedback I get is when two physical bodies have collided with each other and I get both bodies in a "collision handler object".

 

The question: How can I add "logic" to the game?

 

Neither know I those two objects nor do both objects know each other. Sure I have information available like mass, position and velocity but that doesn't help at all.

The real question in games is: Is it a bullet? A unit? A collectable object? Which player owns this object?

 

The only way I have found to solve this problem is to give the physics body a pointer to its related object in my game and make a dynamic_cast in the collision handler to check for all possible classes that differ in how a collision is handled.

 

This has nothing to do with OOP, though. I have read multiple times that this is bad practice in OOP if you don't know the actual class an object is based on anymore during runtime.

 

So how to do it otherwise?

Share this post


Link to post
Share on other sites
The simplest approach is to use masks or type ids in the userdata, and have a global collision response system switch on those.

A heavy-weight approach is to use a general-purpose collision event system that is invoked on any collision. Every bullet listens to its own collisions and responds accordingly.

Independent of those, I recommend getting away from the concept of object types. Focus on behavior instead. e.g., an enemy doesn't _really_ care if it got hit by a bullet or a spike or missile or whatever. It just needs to know that it took damage and what type of damage. If a bullet collides with anything, the bullet can send a damage message to the other object. That object, if it can be damaged, can receive that message and filter it further as necessary (e.g., if the damage type is SPIKE and the object is immune to spike damage, it just ignores the message).

A "production-grade" system likely has elements of all three. Masking is used for optimization, collision events are used to trigger collision game logic, and the collision game logic uses other message to manipulate the game state.

A pseudo-code version might then look something like this:

bullet:
  collision_type = BULLET
  collision_mask = PLAYER|ENEMY // which objects I can collide with

  damage = 10

  oncollide = function(other): // message received whenever I collide with something
    other.sendMessage("ondamage", this.damage, damage_types.BULLET)

enemy:
  collision_type = ENEMY

  hp = 20

  ondamage = function(amount, type): // message received whenever someone tries to damage me
   if type != damage_types.SPIKE:
     this.hp -= amount
     if this.hp <= 0:
       this.die()

That's not all that "OOP" in the bastardized Java-programmer sense that most people are taught, but it's as pure OOP in the original sense as you can get (constructs that encapsulate behavior and communicate via messages).

Share this post


Link to post
Share on other sites
It's pretty common for a third party physics library to use some kind of void user data pointer to allow you to link back a physics object to your game object and while this is generally a bit icky, it's not really solvable in any other general purpose way without introducing unnecessary overhead.

I tend to wrap the physics library (Bullet in my case) in my own thin wrapper that hides such activity away in a central place and makes it generally more compatible with the rest of my code. I dislike using a third party API directly in the parts of the code that just use the physics.

With the void pointer, I only ever assign one type of pointer to it, so in a way I (the programmer) do "know" the class type, even if the compiler doesn't. Rules like this are hard to treat as set in stone in the real world.

Rather than dynamic_casting to lots of different classes, can't you abstractify the things the physics needs to know about into the base class and just treat all your objects as this base inside the physics code? Seems unnecessary for the physics to need to know the exact class details for every object to me.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this