LCOV - code coverage report
Current view: top level - lib/src/geometry - collision_detection.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 52 53 98.1 %
Date: 2021-08-10 15:50:53 Functions: 0 0 -

          Line data    Source code
       1             : import '../../extensions.dart';
       2             : import '../../geometry.dart';
       3             : import '../components/mixins/collidable.dart';
       4             : 
       5           4 : final Set<int> _collidableHashes = {};
       6           4 : final Set<int> _shapeHashes = {};
       7             : 
       8           2 : int _collidableTypeCompare(Collidable a, Collidable b) {
       9          10 :   return a.collidableType.index - b.collidableType.index;
      10             : }
      11             : 
      12             : /// Check whether any [Collidable] in [collidables] collide with each other and
      13             : /// call their onCollision methods accordingly.
      14           2 : void collisionDetection(List<Collidable> collidables) {
      15           2 :   collidables.sort(_collidableTypeCompare);
      16           6 :   for (var x = 0; x < collidables.length; x++) {
      17           2 :     final collidableX = collidables[x];
      18           4 :     if (collidableX.collidableType != CollidableType.active) {
      19             :       break;
      20             :     }
      21             : 
      22           8 :     for (var y = x + 1; y < collidables.length; y++) {
      23           2 :       final collidableY = collidables[y];
      24           4 :       if (collidableY.collidableType == CollidableType.inactive) {
      25             :         break;
      26             :       }
      27             : 
      28           2 :       final intersectionPoints = intersections(collidableX, collidableY);
      29           2 :       if (intersectionPoints.isNotEmpty) {
      30           2 :         collidableX.onCollision(intersectionPoints, collidableY);
      31           2 :         collidableY.onCollision(intersectionPoints, collidableX);
      32           2 :         final collisionHash = _combinedHash(collidableX, collidableY);
      33           4 :         _collidableHashes.add(collisionHash);
      34             :       } else {
      35           2 :         _handleCollisionEnd(collidableX, collidableY);
      36             :       }
      37             :     }
      38             :   }
      39             : }
      40             : 
      41           2 : bool hasActiveCollision(Collidable collidableA, Collidable collidableB) {
      42           4 :   return _collidableHashes.contains(
      43           2 :     _combinedHash(collidableA, collidableB),
      44             :   );
      45             : }
      46             : 
      47           2 : bool hasActiveShapeCollision(HitboxShape shapeA, HitboxShape shapeB) {
      48           4 :   return _shapeHashes.contains(
      49           2 :     _combinedHash(shapeA, shapeB),
      50             :   );
      51             : }
      52             : 
      53           2 : void _handleCollisionEnd(Collidable collidableA, Collidable collidableB) {
      54           2 :   if (hasActiveCollision(collidableA, collidableB)) {
      55           1 :     collidableA.onCollisionEnd(collidableB);
      56           1 :     collidableB.onCollisionEnd(collidableA);
      57           3 :     _collidableHashes.remove(_combinedHash(collidableA, collidableB));
      58             :   }
      59             : }
      60             : 
      61           2 : void _handleShapeCollisionEnd(HitboxShape shapeA, HitboxShape shapeB) {
      62           2 :   if (hasActiveShapeCollision(shapeA, shapeB)) {
      63           2 :     shapeA.onCollisionEnd(shapeB);
      64           2 :     shapeB.onCollisionEnd(shapeA);
      65           3 :     _shapeHashes.remove(_combinedHash(shapeA, shapeB));
      66             :   }
      67             : }
      68             : 
      69             : /// Check what the intersection points of two collidables are
      70             : /// returns an empty list if there are no intersections
      71           2 : Set<Vector2> intersections(
      72             :   Collidable collidableA,
      73             :   Collidable collidableB,
      74             : ) {
      75           2 :   if (!collidableA.possiblyOverlapping(collidableB)) {
      76             :     // These collidables can't have any intersection points
      77           1 :     if (hasActiveCollision(collidableA, collidableB)) {
      78           2 :       for (final shapeA in collidableA.hitboxes) {
      79           2 :         for (final shapeB in collidableB.hitboxes) {
      80           1 :           _handleShapeCollisionEnd(shapeA, shapeB);
      81             :         }
      82             :       }
      83             :     }
      84             :     return {};
      85             :   }
      86             : 
      87             :   final result = <Vector2>{};
      88             :   final currentResult = <Vector2>{};
      89           4 :   for (final shapeA in collidableA.hitboxes) {
      90           4 :     for (final shapeB in collidableB.hitboxes) {
      91           4 :       currentResult.addAll(shapeA.intersections(shapeB));
      92           2 :       if (currentResult.isNotEmpty) {
      93           2 :         result.addAll(currentResult);
      94             :         // Do callbacks to the involved shapes
      95           4 :         shapeA.onCollision(currentResult, shapeB);
      96           4 :         shapeB.onCollision(currentResult, shapeA);
      97           2 :         currentResult.clear();
      98           6 :         _shapeHashes.add(_combinedHash(shapeA, shapeB));
      99             :       } else {
     100           0 :         _handleShapeCollisionEnd(shapeA, shapeB);
     101             :       }
     102             :     }
     103             :   }
     104             :   return result;
     105             : }
     106             : 
     107           2 : int _combinedHash(Object o1, Object o2) {
     108           6 :   return o1.hashCode ^ o2.hashCode;
     109             : }

Generated by: LCOV version 1.15