Jump to content
  • Advertisement
Sign in to follow this  
Bhewnobu

Sphere-Sphere sweep problem

This topic is 2439 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

Hi, i have been making a simple physics simulation with spheres and it works well but in some situations the sweep test I use fails.


// sphere-sphere sweep
// ((p2 + t * v2) - (p1 + t * v1)) * ((p2 + t * v2) - (p1 + t * v1)) = (r1 + r2)^2
// (p2 + t * v2 - p1 - t * v1) * (p2 + t * v2 - p1 - t * v1) = (r1 + r2)^2
// (p2 - p1 + t * (v2 - v1)) * (p2 - p1 + t * (v2 - v1)) = (r1 + r2)^2
// |p2|^2 - 2(p2 dot p1) + t * 2(p2 dot (v2 - v1)) + |p1|^2 - t * 2(p1 dot (v2 - v1)) + (v2 - v1)(v2 - v1) * t^2 = (r1 + r2)^2

// a = (v2 - v1)(v2 - v1)

// b = 2(p2 dot (v2 - v1)) - 2(p1 dot (v2 - v1))
// b = 2(p2 dot (v2 - v1) - p1 dot (v2 - v1))
// b = 2((p2 - p1) dot (v2 - v1))

// c = |p2|^2 - 2(p2 dot p1) + |p1|^2 - (r1 + r2)^2
// c = (p2 dot p2) - 2(p2 dot p1) + (p1 dot p1) - (r1 + r2)^2
// c = (p2 dot p2 - 2 * p2 dot p1 + p1 dot p1) - (r1 + r2)^2
// c = (p2 - p1)(p2 - p1) - (r1 + r2)^2

void CBallManager::CheckCollision(BALL_COLLISION *info)
{
D3DXVECTOR3 vel1 = info->ball1->m_vel * info->dt; //multiply by delta time so it doesnt detect the collision too early
D3DXVECTOR3 vel2 = info->ball2->m_vel * info->dt;

D3DXVECTOR3 vel12 = vel2 - vel1;
if(D3DXVec3LengthSq(&vel12) == 0.0f) //if the balls have equal velocity they cant collide
{
info->collision = false;
return;
}

D3DXVECTOR3 pos12 = info->ball2->m_pos - info->ball1->m_pos;
float r12 = info->ball1->m_radius + info->ball2->m_radius;
float t;

float a = D3DXVec3Dot(&vel12, &vel12);
float b = 2.0f * D3DXVec3Dot(&pos12, &vel12);
float c = D3DXVec3Dot(&pos12, &pos12) - (r12 * r12);
if(GetLowestRoot(a, b, c, t)) //this solves the quadratic and returns the lowest root in t if there is any
{
if(t > 0.0f && t < 1.0f) //if the collision happened in between time moments 0 and 1
{
info->t = t;
info->cPos1 = info->ball1->m_pos + t * vel1; //calculate some stuff for the collision response
info->cPos2 = info->ball2->m_pos + t * vel2;
D3DXVECTOR3 dir = info->cPos2 - info->cPos1;
D3DXVec3Normalize(&dir, &dir);
info->collisionPoint = info->cPos1 + info->ball1->m_radius * dir;

info->d1 = D3DXVec3Length(&(info->cPos1 - info->ball1->m_pos));
info->d2 = D3DXVec3Length(&(info->cPos2 - info->ball2->m_pos));

info->collision = true;
}
}
else
info->collision = false; //no collision occurred
}

Heres the code I use for the sweep, I understand how it works and so on, i have written that code myself and I reduced the equation for fun at the top and it equals the equation that i found in internet so it should be correct. The problem appears when 2 spheres move directly towards each other so that the movement is aligned with X, Y or Z axis. For example if I have a sphere at position (0, 0, 0) with velocity also (0, 0, 0) so its staying still, and other sphere at (100, 0, 0) moving with velocity (-5.0f, 0, 0) directly towards it they will just go through each other. This doesnt happen if they are moving directly towards each other in a arbitrary angle. Is there some mistake in my code or has someone else had the same problem?

Share this post


Link to post
Share on other sites
Advertisement


if(t > 0.0f && t < 1.0f) //if the collision happened in between time moments 0 and 1



Why do you ignore collisions that happen at t==1.0f? I suspect that's what's happening in your case. This should be able to verify with a debugger, however.

Share this post


Link to post
Share on other sites
I changed it to t <= 1.0f and its working well :) Thanks for the response, I just had implemented the ellipsoid collision system from here and it used t < 1.0f in the sample code. I managed to get 2 spheres go through each other at some random angle but i guess thats caused by the collision response code that ill check next.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!