raytrace method
- Ray2 ray, {
- int maxDepth = 10,
- bool hitboxFilter(
- ShapeHitbox candidate
- List<
ShapeHitbox> ? ignoreHitboxes, - List<
RaycastResult< ? out,ShapeHitbox> >
Follows the ray and its reflections until maxDepth
is reached and then
returns all hitboxes, intersection points, normals and reflection rays
(bundled in a list of RaycastResults) from where the ray hits.
maxDepth
is how many times the ray should collide before returning a
result, defaults to 10.
You can provide a hitboxFilter
callback to define which hitboxes
to consider and which to ignore. This callback will be called with
every prospective hitbox, and only if the callback returns true
will the hitbox be considered. Otherwise, the ray will go straight
through it. One common use case is ignoring the component that is
shooting the ray.
If you have a list of hitboxes to ignore in advance,
you can provide them via the ignoreHitboxes
argument.
If out
is provided the RaycastResults in that list be modified and
returned with the result. If there are less objects in out
than the
result requires, the missing RaycastResult objects will be created.
Implementation
@override
Iterable<RaycastResult<ShapeHitbox>> raytrace(
Ray2 ray, {
int maxDepth = 10,
bool Function(ShapeHitbox candidate)? hitboxFilter,
List<ShapeHitbox>? ignoreHitboxes,
List<RaycastResult<ShapeHitbox>>? out,
}) sync* {
out?.forEach((e) => e.reset());
var currentRay = ray;
for (var i = 0; i < maxDepth; i++) {
final hasResultObject = (out?.length ?? 0) > i;
final storeResult =
hasResultObject ? out![i] : RaycastResult<ShapeHitbox>();
final currentResult = raycast(
currentRay,
hitboxFilter: hitboxFilter,
ignoreHitboxes: ignoreHitboxes,
out: storeResult,
);
if (currentResult != null) {
currentRay = storeResult.reflectionRay!;
if (!hasResultObject && out != null) {
out.add(storeResult);
}
yield storeResult;
} else {
break;
}
}
}