protected virtual IEnumerable<Vector4> GetRayForwardIntersect(Vector3 anchor, IEnumerable<Vector3> dir, Real planeOffset)
{
if (dir == null)
yield break;
var vec = new Vector3[4];
var infpt = new[] { 0, 0, 0, 0 }; // 0=finite, 1=infinite, 2=straddles infinity
// find how much the anchor point must be displaced in the plane's
// constant variable
var delta = planeOffset - anchor.z;
// now set the intersection point and note whether it is a
// point at infinity or straddles infinity
var edir = dir.GetEnumerator();
for (var i = 0; i < 4; i++)
{
edir.MoveNext();
var cur = edir.Current;
var test = cur.z * delta;
if (test == 0.0)
{
vec[i] = cur;
infpt[i] = 1;
}
else
{
var lambda = delta / cur.z;
vec[i] = anchor + (lambda * cur);
if (test < 0.0)
infpt[i] = 2;
}
}
for (var i = 0; i < 4; i++)
{
var v = vec[i];
// store the finite intersection points
if (infpt[i] == 0)
yield return new Vector4(v.x, v.y, v.z, 1.0);
else
{
// handle the infinite points of intersection;
// cases split up into the possible frustum planes
// pieces which may contain a finite intersection point
var nextind = (i + 1) % 4;
var prevind = (i + 3) % 4;
if ((infpt[prevind] == 0) || (infpt[nextind] == 0))
{
if (infpt[i] == 1)
yield return new Vector4(v.x, v.y, v.z, 0.0);
else
{
// handle the intersection points that straddle infinity (back-project)
if (infpt[prevind] == 0)
{
var temp = vec[prevind] - vec[i];
yield return new Vector4(temp.x, temp.y, temp.z, 0.0);
}
if (infpt[nextind] == 0)
{
var temp = vec[nextind] - vec[i];
yield return new Vector4(temp.x, temp.y, temp.z, 0.0);
}
}
} // end if we need to add an intersection point to the list
} // end if infinite point needs to be considered
} // end loop over frustun corners
// we end up with either 0, 3, 4, or 5 intersection points
//return res;
}