Sign in to follow this  

Oh 3d collision math gods hear me...

This topic is 2846 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I feel like I am very close, but I can't quite make this work. 3D collision response. I have some test blocks in my program, a 1x1x1 and other targets like more 1x1x1, and a 1x10x1, and 1x10x10. When I smash them together, the results are obviously off. I think there is more energy in the respons than going into it. Things look right when I collide the small block with the larger blocks, but when I collide small blocks with other small blocks they accelerate after the collision. Please help. Below is my code. Section 1 is right after the collision detection, where I set a result that contains the info. Section two is where it get handled. I'm posting it in hopes someone can help me. I think it's pretty broken up and easy to read, let me know if something doesn't make sense. I know the code is not optimized, it's written for clarity.
if (is_collision)
	{
		(*result).IS_COLLISION = TRUE;
		(*result).COLLISION_DIRECTION = ci.COLLISION_DIRECTION;
		(*result).COLLISION_POINT = ci.COLLISION_POINT;

		D3DXVECTOR3 R1 = ci.COLLISION_POINT - ko1->g_Position;
		D3DXVECTOR3 R2 = ci.COLLISION_POINT - ko2->g_Position;

		D3DXVECTOR3 rotation_velocity_1;
		D3DXVECTOR3 rotation_velocity_2;

		D3DXVec3Cross(&rotation_velocity_1,&ko1->g_AngularVelocity_World,&R1);
		D3DXVec3Cross(&rotation_velocity_2,&ko2->g_AngularVelocity_World,&R2);

		D3DXVECTOR3 ko_1_collision_point_velocity = ko1->g_LinearVelocity_World + rotation_velocity_1;
		D3DXVECTOR3 ko_2_collision_point_velocity = ko2->g_LinearVelocity_World + rotation_velocity_2;

		D3DXVECTOR3 velocity_difference = ko_1_collision_point_velocity - ko_2_collision_point_velocity;

		float closing_velocity = D3DXVec3Dot(&velocity_difference,&ci.COLLISION_DIRECTION);
		
		(*result).CLOSING_VELOCITY = closing_velocity;

		return 0;
	}


Then it gets handled here, I think the equation must be wrong somewhere but it looks right based on material I'm reading. 'koe' is my 'kinetic object event' which holds a pointer to the two kinetic objects (ko one and two) and the collision result (cr) info.
const float e = 0.25f;  // coefficient of restitution

			D3DXVECTOR3 n, collisionPoint;
			n = koe.cr.COLLISION_DIRECTION;
			collisionPoint = koe.cr.COLLISION_POINT;

			D3DXVECTOR3 R1 = collisionPoint - koe.one->g_Position;
			D3DXVECTOR3 R2 = collisionPoint - koe.two->g_Position;

			D3DXVECTOR3 cross1;
			D3DXVECTOR3 cross2;

			D3DXVec3Cross(&cross1,&R1,&n);
			D3DXVec3Cross(&cross2,&R2,&n);

			D3DXVec3TransformCoord(&cross1,&cross1,&koe.one->g_InertiaTensorInverse);
			D3DXVec3TransformCoord(&cross1,&cross1,&koe.two->g_InertiaTensorInverse);

			D3DXVECTOR3 crossA;
			D3DXVECTOR3 crossB;
			D3DXVec3Cross(&crossA,&cross1,&R1);
			D3DXVec3Cross(&crossB,&cross1,&R2);

			D3DXVECTOR3 sum = crossA + crossB; //cross sum...
			FLOAT sum_dot_normal = D3DXVec3Dot(&sum,&n);

			FLOAT one_over_mass =  1.0f / (1.0f/koe.one->g_Mass + 1.0f/koe.two->g_Mass);

			float numerator = -(e + 1.0f) * koe.cr.CLOSING_VELOCITY;
			float denominator = one_over_mass + sum_dot_normal;

			float j = numerator/denominator;  
			D3DXVECTOR3 j_vector = n*j;

			D3DXVECTOR3 angular_add_1;
			D3DXVECTOR3 angular_add_2;

			D3DXVec3Cross(&angular_add_1,&R1,&j_vector);
			D3DXVec3TransformCoord(&angular_add_1,&angular_add_1,&koe.one->g_InertiaTensorInverse);

			D3DXVec3Cross(&angular_add_2,&R2,&j_vector);
			D3DXVec3TransformCoord(&angular_add_2,&angular_add_2,&koe.two->g_InertiaTensorInverse);

			koe.one->g_LinearVelocity_World += j_vector / koe.one->g_Mass;
			koe.one->g_AngularVelocity_World += angular_add_1;

			koe.two->g_LinearVelocity_World -= j_vector / koe.two->g_Mass;
			koe.two->g_AngularVelocity_World += angular_add_2;
Thanks much in advance for anyone with a head for this stuff. God help us all. -Matt

Share this post


Link to post
Share on other sites

This topic is 2846 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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