public override bool Raycast(RayCastOutput output, RayCastInput input, Transform xf, int childIndex)
{
// Put the ray into the edge's frame of reference.
Vec2 p1 = pool0.Set(input.P1).SubLocal(xf.P);
Rot.MulTrans(xf.Q, p1, p1);
Vec2 p2 = pool1.Set(input.P2).SubLocal(xf.P);
Rot.MulTrans(xf.Q, p1, p1);
Vec2 d = p2.SubLocal(p1); // we don't use p2 later
Vec2 v1 = Vertex1;
Vec2 v2 = Vertex2;
Vec2 normal = pool2.Set(v2).SubLocal(v1);
normal.Set(normal.Y, -normal.X);
normal.Normalize();
// q = p1 + t * d
// dot(normal, q - v1) = 0
// dot(normal, p1 - v1) + t * dot(normal, d) = 0
pool3.Set(v1).SubLocal(p1);
float numerator = Vec2.Dot(normal, pool3);
float denominator = Vec2.Dot(normal, d);
if (denominator == 0.0f)
{
return false;
}
float t = numerator / denominator;
if (t < 0.0f || 1.0f < t)
{
return false;
}
Vec2 q = pool3;
Vec2 r = pool4;
// Vec2 q = p1 + t * d;
q.Set(d).MulLocal(t).AddLocal(p1);
// q = v1 + s * r
// s = dot(q - v1, r) / dot(r, r)
// Vec2 r = v2 - v1;
r.Set(v2).SubLocal(v1);
float rr = Vec2.Dot(r, r);
if (rr == 0.0f)
{
return false;
}
pool5.Set(q).SubLocal(v1);
float s = Vec2.Dot(pool5, r) / rr;
if (s < 0.0f || 1.0f < s)
{
return false;
}
output.Fraction = t;
if (numerator > 0.0f)
{
// argOutput.normal = -normal;
output.Normal.Set(normal).NegateLocal();
}
else
{
// output.normal = normal;
output.Normal.Set(normal);
}
return true;
}