//----------------------------------------------------------------//
bool USSurface2D::GetHit ( ZLVec2D& sphereLoc, ZLVec2D& move, SurfaceHit2D& hit ) {

	// The usual stuff...
	ZLVec2D unitMove = move;
	unitMove.Norm ();
	
	if ( unitMove.Dot ( this->mNorm ) >= -0.001f ) return false;
	if ( ZLDist::PointToPlane2D ( sphereLoc, *this ) <= 0.0f ) return false;
	
	// Get the point of first contact on the polygon...
	ZLVec2D pofcop = this->mNorm;
	pofcop.Reverse ();
	pofcop.Add ( sphereLoc );
	this->ClampPoint ( pofcop );

	// Send a ray from the point on the surface to intersect the circle.
	// The ray is the inverse of the move vec.
	ZLVec2D inverseMove = move;
	inverseMove.Reverse ();

	float t0, t1;
	u32 sectType;
	sectType = ZLSect::VecToCircle ( t0, t1, pofcop, inverseMove, sphereLoc, 1.0f );

	// Bail if the point will not intersect the sphere.
	if ( sectType == ZLSect::SECT_PARALLEL ) return false;

	if ( t0 >= hit.mTime ) return false;

	// Bail if the point will graze the sphere.
	if ( sectType == ZLSect::SECT_TANGENT ) return false;

	// Bail if the point will stay outside of the sphere.
	if (( t0 > 1.0f ) || ( t1 < 0.0f )) return false;

	// OMG!  We hit something!

	float time = t0;
	
	hit.mTime = time;

	inverseMove.Scale ( t0 );
	hit.mPoint = pofcop;
	hit.mPoint.Add ( inverseMove );
	
	hit.mNorm = sphereLoc;
	hit.mNorm.Sub ( hit.mPoint );
	hit.mNorm.Norm ();
	
	if ( unitMove.Dot ( hit.mNorm ) >= -0.001f ) return false;
	
	return true;
}
//----------------------------------------------------------------//
bool USSurface2D::GetTouch ( ZLVec2D& sphereLoc, ZLSurfaceTouch2D& touch ) {

	// The usual stuff...
	float dist = ZLDist::PointToPlane2D ( sphereLoc, *this );
	if ( dist <= 0.0f ) return false;
	if ( dist > 1.001f ) return false;
	
	// Get the point of first contact on the polygon...
	ZLVec2D pofcop = this->mNorm;
	pofcop.Reverse ();
	pofcop.Add ( sphereLoc );
	this->ClampPoint ( pofcop );

	ZLVec2D ray = pofcop;
	ray.Sub ( sphereLoc );
	dist = ray.NormSafe ();
	
	if ( dist >= touch.mDist ) return false;

	float dot = ray.Dot ( touch.mFinger );
	if ( dot < 0.85f ) return false;

	// we have a touch...
	touch.mDist = dist;
	touch.mPoint = pofcop;
	touch.mTouch = true;
	touch.mHit = !touch.mPrevTouch;
	//touch.mNorm = this->GetNorm ();
	
	return true;
}
//----------------------------------------------------------------//
float USSurface2D::GetDepthAlongRay ( ZLVec2D& sphereLoc, ZLVec2D& ray ) {
	
	// Get the point of first contact on the polygon...
	ZLVec2D pofcop = this->mNorm;
	pofcop.Reverse ();
	pofcop.Add ( sphereLoc );
	this->ClampPoint ( pofcop );

	float t0, t1;
	u32 sectType;
	sectType = ZLSect::VecToCircle ( t0, t1, pofcop, ray, sphereLoc, 1.0f );

	// Bail if the point will not intersect the sphere.
	if ( sectType == ZLSect::SECT_PARALLEL ) return 0.0f;
	if ( sectType == ZLSect::SECT_TANGENT ) return 0.0f;

	return t0;
}
//----------------------------------------------------------------//
bool USSurface2D::GetContact ( ZLVec2D& sphereLoc, ZLVec2D& contact, ZLVec2D& norm ) {

	// The usual stuff...
	float dist = ZLDist::PointToPlane2D ( sphereLoc, *this );
	if ( dist <= 0.0f ) return false;
	if ( dist > 1.001f ) return false;
	
	// Get the point of first contact on the polygon...
	contact = this->mNorm;
	contact.Reverse ();
	contact.Add ( sphereLoc );
	this->ClampPoint ( contact );

	norm = sphereLoc;
	norm.Sub ( contact );
	dist = norm.NormSafe ();
	
	if ( dist > 1.001f ) return false;
	return true;
}