Sphere collision physics

BlitzMax Forums/MiniB3D Module/Sphere collision physics

ima747(Posted 2009) [#1]
I'm trying to figure out how to alter a sphere's velocity when it collides with a mesh. Using the CollisionX/Y/Z I get the position of the collision, then I subtract that from the position of the sphere and divide the result by the radius which should give me the percentage to affect the X/Y or Z vector by, I thought. It seems to work perfectly for Y (affected by gravity) on flat surfaces, but angled surfaces and using the same math for X and Y cause it to freak out.

I'm using iMiniB3D and it could be that CollisionX/Y/Z don't work quite right but I'm assuming it's me and working back from there. I'm going to punch up an example in minib3d to see if it's the engine or me, but does anyone have an example of how to do sphere to mesh collision physics lying around? I've come up empty in my searches...


ima747(Posted 2009) [#2]
After making a test in minib3d it seems it's the CollisionX/Y/Z functions. I'm still getting collision positions beyond the radius of the sphere which results in the momentum getting multiplied and bad things ensue.


ima747(Posted 2009) [#3]
I recalled an example that I was pointed to for another question recently but couldn't get working looked like it had the physics in it so I went digging and sure enough they work. Here is the code for iMiniB3D, if there's interest and anyone gets confused by the C syntax I'll translate it over to blitz.

core is the collision entity (I use a pivot and attach the actual mesh to that so I can rotate them independently). mx/my/mz are floats with the momentum of the ball along the various axis. kBounceyness is a float with how bouncy the collision is (1 would be perfect bouncyness, 0 would be no bounce at all. normally this would be a factor of how bouncy the ball is and how bouncy the surface is, but this is just a basic example an there are no materials. appropriate bouncyness will be affected by your scale and relative movement speeds.)

The collisions you should set should be Collisions(balltype, worldtype, 2, 2);

Hope this helps someone as I found it a bit tricky to track down.
for(int collision = 1; collision <= core->CountCollisions(); collision++) {
			// Get normal of surface which we collided with
			float Nx = core->CollisionNX(collision);
			float Ny = core->CollisionNY(collision);
			float Nz = core->CollisionNZ(collision);
			
			// compute the dot product of the momentum and the normal
			float VdotN = mx*Nx + my*Ny + mz*Nz;
			
			// calculate normal forces
			float NFx = -2.0 * Nx * VdotN;
			float NFy = -2.0 * Ny * VdotN;
			float NFz = -2.0 * Nz * VdotN;
			
			// add normal forces to momentums
			mx += NFx * kBounceyness;
			my += NFy * kBounceyness;
			mz += NFz * kBounceyness;

		}
	}


P.S. I barely understand how collision normals work and that's the key to this so I'm afraid I can't really explain it all that well.