Sign in to follow this  
ms291052

sphere / mesh (level) collision question

Recommended Posts

ms291052    223
I have created a routine that I call when the player (bounded by a sphere) wants to move from p1 to p2. This works in that the player's midpoint never goes through a wall, but I'm not entirely sure how to implement the radius into all of this.
Vector3 cLevel::GetMovePos(Vector3* p1, Vector3* p2, float radius, DWORD depth = 0)
{
	//If this function recurses more than three times, give up
	if(depth > 3)
		return *p1;

	DWORD face = -1;
	Vector3 p;
	Plane l;
	Vector3 dir = (*p2 - *p1);
	//Intersect takes two points, p1 and p2. It returns a bool stating whether or not this line segment
	//intersects the level's mesh. If so, p(Vector3) is filled with the point at which they intersect,
	//and face is filled with the face (DWORD) index of the hit triangle.
	BOOL hit = Intersect(p1, p2, &p, &face);
	if(hit)
	{
		//This code block just fills t0, t1, and t2 with the proper Vector3's for the three vertices of the intersected triangle
		const sTriangle* tri = m_pLevel.GetTriangle(face);
		Vector3 t0 = m_pLevel.GetVertex(tri->index0)->pos;
		Vector3 t1 = m_pLevel.GetVertex(tri->index1)->pos;
		Vector3 t2 = m_pLevel.GetVertex(tri->index2)->pos;

		//Determine the plane and the normal
		PlaneFromPoints(&l, &t0, &t1, &t2);
		NormalizePlane(&l, &l);
		Vector3 n = Vector3(l.a, l.b, l.c);
		//dp now holds the perpendicular component of "velocity", i.e. p2 - p1
		//Thus (p2 - p1) 2 dp is perpendicular to the plane, making the sphere slide across the surface
		Vector3 dp = n * Dot(&dir, &n);

		//*p1 + dir - dp = *p2 - dp but the original is maintained (for now) for readability
		//Since the new position may intersect the mesh again we have to recheck with it as our new p2
		Vector3 r = GetMovePos(p1, &(*p1 + dir - dp), radius, depth+1);
		return r;
	}
	return *p2;
}

void HandleInput(float DeltaTime)
{
    Vector3 velo;
    //Get input and all, which stores result in velo
    Player->SetPosition(Level->GetMovePos(&Player->GetPosition(), &(Player->GetPosition() + velo * DeltaTime), Player->GetRadius())
}

By my best thinking I should just multiply the plane's normal by radius during GetMovePos, but this still lets me get too close to a wall, then when the midpoint collides with the wall the player's sphere gets moved back tangent to the wall again creating an awful bouncing effect. Help appreciated! ms

Share this post


Link to post
Share on other sites
jyk    2094
It's my understanding that the paper mentioned above has some algorithmic problems, so I would also recommend the paper 'Improved Collision Detection and Response', by Kasper Fauerby, aka Telemachos. It's based on the concepts in the 'Ellipsoids' paper, but takes a more robust approach.

Share this post


Link to post
Share on other sites

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