public override bool rayCast( out RayCastOutput output, ref RayCastInput input, ref Transform transform, int childIndex )
{
output = new RayCastOutput();
// Put the ray into the polygon's frame of reference.
Vector2 p1 = MathUtils.mulT( transform.q, input.Point1 - transform.p );
Vector2 p2 = MathUtils.mulT( transform.q, input.Point2 - transform.p );
Vector2 d = p2 - p1;
float lower = 0.0f, upper = input.MaxFraction;
int index = -1;
for( int i = 0; i < vertices.Count; ++i )
{
// p = p1 + a * d
// dot(normal, p - v) = 0
// dot(normal, p1 - v) + a * dot(normal, d) = 0
float numerator = Vector2.Dot( normals[i], vertices[i] - p1 );
float denominator = Vector2.Dot( normals[i], d );
if( denominator == 0.0f )
{
if( numerator < 0.0f )
{
return false;
}
}
else
{
// Note: we want this predicate without division:
// lower < numerator / denominator, where denominator < 0
// Since denominator < 0, we have to flip the inequality:
// lower < numerator / denominator <==> denominator * lower > numerator.
if( denominator < 0.0f && numerator < lower * denominator )
{
// Increase lower.
// The segment enters this half-space.
lower = numerator / denominator;
index = i;
}
else if( denominator > 0.0f && numerator < upper * denominator )
{
// Decrease upper.
// The segment exits this half-space.
upper = numerator / denominator;
}
}
// The use of epsilon here causes the assert on lower to trip
// in some cases. Apparently the use of epsilon was to make edge
// shapes work, but now those are handled separately.
//if (upper < lower - b2_epsilon)
if( upper < lower )
{
return false;
}
}
Debug.Assert( 0.0f <= lower && lower <= input.MaxFraction );
if( index >= 0 )
{
output.Fraction = lower;
output.Normal = MathUtils.mul( transform.q, normals[index] );
return true;
}
return false;
}