| 105 | } |
| 106 | |
| 107 | Maybe<pair<Vec2F, Maybe<Vec2F>>> World::lineCollision(Line2F const& line, CollisionSet const& collisionSet) const { |
| 108 | auto geometry = this->geometry(); |
| 109 | Maybe<PolyF> intersectPoly; |
| 110 | Maybe<PolyF::LineIntersectResult> closestIntersection; |
| 111 | |
| 112 | forEachCollisionBlock(RectI::integral(RectF::boundBoxOf(line.min(), line.max()).padded(1)), [&](CollisionBlock const& block) { |
| 113 | if (block.poly.isNull() || !isColliding(block.kind, collisionSet)) |
| 114 | return; |
| 115 | |
| 116 | Vec2F nearMin = geometry.nearestTo(block.poly.center(), line.min()); |
| 117 | auto intersection = block.poly.lineIntersection(Line2F(nearMin, nearMin + line.diff())); |
| 118 | if (intersection && (!closestIntersection || intersection->along < closestIntersection->along)) { |
| 119 | intersectPoly = block.poly; |
| 120 | closestIntersection = intersection; |
| 121 | } |
| 122 | }); |
| 123 | |
| 124 | if (closestIntersection) { |
| 125 | auto point = line.eval(closestIntersection->along); |
| 126 | auto normal = closestIntersection->intersectedSide.apply([&](uint64_t side) { return intersectPoly->normal(side); }); |
| 127 | return make_pair(point, normal); |
| 128 | } |
| 129 | return {}; |
| 130 | } |
| 131 | |
| 132 | bool World::polyCollision(PolyF const& poly, CollisionSet const& collisionSet) const { |
| 133 | auto geometry = this->geometry(); |
nothing calls this directly
no test coverage detected