sphere / mesh (level) collision question

Started by
1 comment, last by Zakwayda 19 years, 4 months ago
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
Advertisement
There is a very good article that explains the collision detection with spheres very nicely:

General Collision Detection for Games Using Ellipsoids
Give a man a fish and you feed him for a day; teach him to use the Net and he won't bother you for weeks.
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.

This topic is closed to new replies.

Advertisement