Equivalent to onCollisionEnter event

Post Reply
JackR
Posts: 2
Joined: Sun Jun 12, 2016 5:42 pm

Equivalent to onCollisionEnter event

Post by JackR »

Hi guys, doing a basic implementation of Bullet in a directX engine. I've got everything running, objects are colliding with each other and what not.

I just can't figure out how to get collision events from within a custom class I made. I've worked with Box2D before and from within classes I could call
the collision listener and check for the colliding objects tags and launch events depending on the other objects tags. (Using a switch).

Very similar to Unity or UE4 collision triggering events.

I couldn't find anything that replicates this with Bullet, so I've tried something else:

Code: Select all

void App::Update()
{
	int numManifolds = WORLD->getDispatcher()->getNumManifolds();
	for (int i = 0; i<numManifolds; i++)
	{
		btPersistentManifold* contactManifold = WORLD->getDispatcher()->getManifoldByIndexInternal(i);
		btCollisionObject* obA = const_cast<btCollisionObject*>(contactManifold->getBody0());
		btCollisionObject* obB = const_cast<btCollisionObject*>(contactManifold->getBody1());

		if ((obA->getCollisionFlags() == COL_BULLET && obB->getCollisionFlags() == COL_BUBBLE) || (obA->getCollisionFlags() == COL_BUBBLE && obB->getCollisionFlags() == COL_BULLET))
		{
			bool isColliding = obA->checkCollideWith(obB);
			if (isColliding)
			{
				if (obA->getCollisionFlags() == COL_BUBBLE)
				{
					obA->setCollisionFlags(COL_BUBBLE_TOUCHED);
					int index = WORLD->getCollisionWorld()->getCollisionObjectArray().findBinarySearch(obA);
					WORLD->getCollisionWorld()->getCollisionObjectArray().at(index)->setCollisionFlags(COL_BUBBLE_TOUCHED);
				}
				else if (obB->getCollisionFlags() == COL_BUBBLE)
				{
					obB->setCollisionFlags(COL_BUBBLE_TOUCHED);
					int index = WORLD->getCollisionWorld()->getCollisionObjectArray().findBinarySearch(obA);
					WORLD->getCollisionWorld()->getCollisionObjectArray().at(index)->setCollisionFlags(COL_BUBBLE_TOUCHED);
				}
                        }
		}
	}
}
App is just a container class to run the gameloop from. It has reference to every object in the game/scene.

Then this is being called:

Code: Select all

void Bubble::Update()
{
	GameObject::Update();
	//std::cout << body->getCollisionFlags() << std::endl;
	
	if (body->getCollisionFlags() == bubbleTouched)
	{
		body->getWorldTransform().setOrigin(btVector3(1000,0,0));
	}
}
Now, in the App::Update, when I print the object's CollisionTag it's working correctly.
Then I print it from the actual object's Update and it's back to it's original state. (My guess is it never actually changed)

What am I doing wrong? Please :)

ps: These are the flags I'm using:

Code: Select all

#define BIT(x) (1<<(x))
enum collisiontypes {
	COL_NOTHING = 0, //<Collide with nothing
	COL_BUBBLE = BIT(0), //<Collide with bubbles
	COL_WALL = BIT(1), //<Collide with walls
	COL_BULLET = BIT(2), //<Collide with bullets
	COL_BUBBLE_TOUCHED = BIT(3)
};

static const int bulletCollidesWith = COL_WALL | COL_BUBBLE | COL_BUBBLE_TOUCHED;
static const int wallCollidesWith = COL_NOTHING;
static const int bubbleCollidesWith = COL_BULLET;
static const int bubbleTouched = COL_BULLET | COL_BUBBLE_TOUCHED;
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Equivalent to onCollisionEnter event

Post by benelot »

You need to use the userpointers. At the point where you get the btCollisionObjects obA and obB, you can check if num contacts is >0. If yes, the two objects collide. Then you can receive your game object by getting the userpointer you set when you build the btRigidBodies (setUserPointer, getUserPointer). Cast them into your game object, it is safe to do so. Then you can access everything you want. You can have a reference of your rigidbody in your game object to manipulate it or set a tag in your game object etc.

Does that solve your problem?
Post Reply