Skip to content

Commit

Permalink
Use sync* for raytrace
Browse files Browse the repository at this point in the history
  • Loading branch information
spydon committed Aug 12, 2022
1 parent 1de3317 commit b7e1d02
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 18 deletions.
10 changes: 6 additions & 4 deletions packages/flame/lib/src/collisions/collision_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,19 @@ abstract class CollisionDetection<T extends Hitbox<T>> {
List<RaycastResult<T>>? out,
});

/// Gives back all hitboxes and intersection points the ray hits.
/// 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 [RaycastResult]s) from where the ray hits.
///
/// [maxDepth] is how many times the ray should collide before returning a
/// result, defaults to 100.
/// result, defaults to 10.
///
/// If [out] is provided the [RaycastResult]s 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.
List<RaycastResult<T>> raytrace(
Iterable<RaycastResult<T>> raytrace(
Ray2 ray, {
double maxDepth = 100,
double maxDepth = 10,
List<RaycastResult<T>>? out,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,12 @@ class StandardCollisionDetection extends CollisionDetection<ShapeHitbox> {
}

@override
List<RaycastResult<ShapeHitbox>> raytrace(
Iterable<RaycastResult<ShapeHitbox>> raytrace(
Ray2 ray, {
double maxDepth = 100,
double maxDepth = 10,
List<RaycastResult<ShapeHitbox>>? out,
}) {
}) sync* {
out?.forEach((e) => e.reset());
final result = out ?? <RaycastResult<ShapeHitbox>>[];
var currentRay = ray;
for (var i = 0; i < maxDepth; i++) {
Expand All @@ -145,14 +146,11 @@ class StandardCollisionDetection extends CollisionDetection<ShapeHitbox> {
currentRay = currentResult.reflectionRay!;
if (!hasResultObject) {
result.add(currentResult);
yield currentResult;
}
} else {
for (var j = i; j < result.length; j++) {
result[j].reset();
}
break;
}
}
return result;
}
}
16 changes: 9 additions & 7 deletions packages/flame/test/collisions/collision_detection_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ void main() {
)..add(CircleHitbox());
await game.ensureAddAll([circle1, circle2]);
final ray = Ray2(Vector2(0, 10), Vector2.all(1.0)..normalize());
final results = game.collisionDetection.raytrace(ray);
final results = game.collisionDetection.raytrace(ray).toList();
expect(results.length, 2);
expect(results.every((e) => e.isActive), isTrue);
expect(results.every((e) => e.isInsideHitbox), isFalse);
Expand Down Expand Up @@ -1146,7 +1146,7 @@ void main() {
)..add(RectangleHitbox());
await game.ensureAddAll([rectangle1, rectangle2]);
final ray = Ray2(Vector2(0, 10), Vector2.all(1.0)..normalize());
final results = game.collisionDetection.raytrace(ray);
final results = game.collisionDetection.raytrace(ray).toList();
expect(results.length, 2);
expect(results.every((e) => e.isActive), isTrue);
expect(results.every((e) => e.isInsideHitbox), isFalse);
Expand All @@ -1156,7 +1156,8 @@ void main() {
final reflectionRay1 = results[0].reflectionRay;
expect(reflectionRay1?.origin, Vector2(10, 20));
expect(reflectionRay1?.direction, Vector2(-1, 1)..normalize());
final results2 = game.collisionDetection.raytrace(reflectionRay1!);
final results2 =
game.collisionDetection.raytrace(reflectionRay1!).toList();
expect(results2.length, 1);
// Second box
expect(results[1].intersectionPoint, Vector2(-10, 40));
Expand All @@ -1176,8 +1177,8 @@ void main() {
)..add(RectangleHitbox());
await game.ensureAddAll([rectangle1, rectangle2]);
final ray = Ray2(Vector2(20, 10), Vector2(1, 1)..normalize());
final results = game.collisionDetection.raytrace(ray);
expect(results.length, 100);
final results = game.collisionDetection.raytrace(ray).toList();
expect(results.length, 10);
expect(results.every((e) => e.isActive), isTrue);
expect(results[0].isInsideHitbox, isFalse);
expect(results[1].isInsideHitbox, isTrue);
Expand All @@ -1187,8 +1188,9 @@ void main() {
final reflectionRay1 = results[0].reflectionRay;
expect(reflectionRay1?.origin, Vector2(30, 20));
expect(reflectionRay1?.direction, Vector2(1, -1)..normalize());
final results2 = game.collisionDetection.raytrace(reflectionRay1!);
expect(results2.length, 100);
final results2 =
game.collisionDetection.raytrace(reflectionRay1!).toList();
expect(results2.length, 10);
// Second box
expect(results[1].intersectionPoint, Vector2(50, 0));
expect(results[1].normal, Vector2(0, 1));
Expand Down

0 comments on commit b7e1d02

Please sign in to comment.