Imperfect reflection of Rigidbodys

Mind In A Box
Posts: 7
Joined: Thu Jul 15, 2010 10:42 am

Imperfect reflection of Rigidbodys

Post by Mind In A Box »

Hi,

we are currently making a game where it is crucial to have perfect reflection of rigidbodys versus triangle-meshes. Though, it is working most of the times right now, sometimes it doesn't.

Here's a picture of one of our levels so you get the idea:
Image

We have a ball which you have to give a kick to get it to the goal at the end. In this level you have to use the fences as reflector to get to the goal in lesser turns.
However, the ball will sometimes just come back in the same angle as it was shot into the fence, ending up at the position from where you shot it from, which is quite annoying. In some other cases the ball is just reflected at a wrong angle.

Would be nice if someone has a solution or maybe some tips on how to solve this.

Thanks in advance!

Edit: Here's a picture of what happens with the normals of the contactpoints. You can clearly see that there is a wrong one which causes our problems :(

Image
Basroil
Posts: 463
Joined: Fri Nov 30, 2012 4:50 am

Re: Imperfect reflection of Rigidbodys

Post by Basroil »

Assuming you only "shoot" the ball once a turn, why bother with full physics? Why not just calculate the reactions by hand (using collision data from bullet)? Doing that will give you greater control over ball dynamics.

As for triangle mesh bounces in bullet, perhaps the ball is hitting triangle edges rather than faces? Some people have similar issues with "cars" suddenly jumping on triangle boundaries. Tried convex decomposition instead? Worth looking into since the calculation methods are different.

P.S. I like your graphic style, very well thought out and very easy to see. Has that game board feel to it.
Mind In A Box
Posts: 7
Joined: Thu Jul 15, 2010 10:42 am

Re: Imperfect reflection of Rigidbodys

Post by Mind In A Box »

Assuming you only "shoot" the ball once a turn, why bother with full physics? Why not just calculate the reactions by hand (using collision data from bullet)? Doing that will give you greater control over ball dynamics.
What exactly do you mean by that? We already do some manual computation of things like rolling friction, limiting z-velocity, etc. But how would I compute the whole thing manually if bullet doesn't even report the right normal?
As for triangle mesh bounces in bullet, perhaps the ball is hitting triangle edges rather than faces? Some people have similar issues with "cars" suddenly jumping on triangle boundaries. Tried convex decomposition instead? Worth looking into since the calculation methods are different.
After some testing I did today, I think that the ball is getting the wrong normal more from the pole behind the fence, because the wrong normals always are in front of them. Probably the ball penetrates the fence too deep and collides with the pole instead of the fence?
I enabled CCD for that matter, though. Maybe increasing the simulation steps or something similar will help? (Or our artist just scraps those damn poles ;) )
P.S. I like your graphic style, very well thought out and very easy to see. Has that game board feel to it.
Thanks, I'll tell our artist :)
There's more here, if you want to see: http://www.indiedb.com/games/just-hot-air

Edit: Another problem is when the ball is hitting the edges of the fence. And I have seen some cases where the normal was right, but the ball was also reflected in the wrong way, though, that did only happen like 1 or 2 times so far. Maybe my debug-function just didnt catch that wrong normal.
dern23
Posts: 26
Joined: Thu Oct 04, 2012 1:58 pm

Re: Imperfect reflection of Rigidbodys

Post by dern23 »

If you've implemented the debug drawing interface, you should be able to see if there are degenerate contacts being created, say from the post as you suggested; or if there are issues with the terrain mesh edge normals. To fix the latter problem you can use the set the global callback 'gContactAddedCallback' to a function that overwrites the errornous edge normal like so:

Code: Select all

static bool terrainNormalCallback(btManifoldPoint& cp, int removeIndex, btPersistentManifold* pm,	const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{
	const btTriangleShape* tShape = NULL;
	btCollisionObject* colObj = NULL;
	if( colObj0Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE )
	{
		colObj = colObj0Wrap->getCollisionObject();
		tShape = static_cast<const btTriangleShape*>(colObj0Wrap->getCollisionShape());
	}
	else if( colObj1Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE )
	{
		colObj = colObj1Wrap->getCollisionObject();
		tShape = static_cast<const btTriangleShape*>(colObj1Wrap->getCollisionShape());
	}

	const btCollisionShape *parent = colObj ->getCollisionShape();
	if (parent->getShapeType() != TERRAIN_SHAPE_PROXYTYPE) return;

	btVector3 tri_normal;
	tshape->calcNormal(tri_normal);
	cp.m_normalWorldOnB = colObj->getWorldTransform().getBasis() * tri_normal;

	// Re-project collision point along normal.
	cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
	cp.m_localPointB = colObj->getWorldTransform().invXform(cp.m_positionWorldOnB);
	return true;
}
Some code could be added to this method to check for problems of the first case as well. If the check passes, remove the contact with pm->removeContactPoint(removeIndex).

Edit: Check both objects just in case, can't remember if Bullet guarantees order or not.
Last edited by dern23 on Wed Sep 25, 2013 1:27 pm, edited 1 time in total.
Mind In A Box
Posts: 7
Joined: Thu Jul 15, 2010 10:42 am

Re: Imperfect reflection of Rigidbodys

Post by Mind In A Box »

I'm pretty sure now that the problem only occurs when the ball is directly hitting the point where the post is behind the fence or when it hits the end of the fence to the left or right.

Both can be worked around by our artist, by removing the posts and putting a plane over the gaps between the fences at important places, IF this really is the problem.

Another solution could be to use a softbody, isn't it? It would average the collision and not take only one point, right?

I've never worked with softbodys before, but shall I give it a try?
dern23
Posts: 26
Joined: Thu Oct 04, 2012 1:58 pm

Re: Imperfect reflection of Rigidbodys

Post by dern23 »

Soft body would be overkill and wouldn't solve your problem. I demonstrated how to fix normals for a terrain mesh, but you can adapt that code to any collision shape type and use some basic linear algebra to set the normals to be whatever you desire. You can even use the user pointer from btCollisionObject* if you wish to incorporate high-level game logic into the contact filtering callback. It's completely user-controllable and much simpler than having to refactor and test everything to include soft bodies (which in my experience are often more trouble than they are worth).
Mind In A Box
Posts: 7
Joined: Thu Jul 15, 2010 10:42 am

Re: Imperfect reflection of Rigidbodys

Post by Mind In A Box »

We now solved it by increasing the tickrate and using a modified collisionshape:
Image

and

Image

Unfortunately I didn't get your code to work properly (ball falling through the ground, etc) so this is how we solved it for now. Thanks for your help, though :)
dern23
Posts: 26
Joined: Thu Oct 04, 2012 1:58 pm

Re: Imperfect reflection of Rigidbodys

Post by dern23 »

I forgot to mention to trigger the callback you have to set the collision flag on the bullet collision object like

Code: Select all

terrain->setCollisionFlags( terrain->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK );
Otherwise you'll have exactly the behavior you described!
Adjusting the model dimensions is certainly a valid solution to getting rid of weird contact issues, but it never hurts to remember there are other options if needed. Like most things it depends on the particular situation as to which is the appropriate approach.
Glad to hear it was resolved though! :D