| 260 | } |
| 261 | |
| 262 | bool PhysicsWorld::query(const Rect& rect, const std::function<bool(Body*)>& callback) { |
| 263 | AssertUnless(_world, "accessing invalid physics world."); |
| 264 | auto& world = *_world; |
| 265 | pd::AABB aabb{ |
| 266 | pd::AABB::Location{ |
| 267 | prVal(rect.getLeft()), |
| 268 | prVal(rect.getBottom())}, |
| 269 | pd::AABB::Location{ |
| 270 | prVal(rect.getRight()), |
| 271 | prVal(rect.getTop())}}; |
| 272 | pd::Transformation transform{ |
| 273 | pr::Length2{ |
| 274 | prVal(rect.getCenterX()), |
| 275 | prVal(rect.getCenterY())}}; |
| 276 | pd::Shape testShape = pd::Shape{ |
| 277 | pd::PolygonShapeConf{ |
| 278 | prVal(rect.size.width), |
| 279 | prVal(rect.size.height)}}; |
| 280 | pd::Query(pd::GetTree(world), aabb, [&](pr::BodyID bodyID, pr::ShapeID shapeID, const pr::ChildCounter) { |
| 281 | BLOCK_START { |
| 282 | BREAK_IF(pd::IsSensor(world, shapeID)); |
| 283 | const auto shapeType = pd::GetType(world, shapeID); |
| 284 | bool isCommonShape = shapeType != pr::GetTypeID<pd::ChainShapeConf>() && shapeType != pr::GetTypeID<pd::EdgeShapeConf>(); |
| 285 | const auto shape = pd::GetShape(world, shapeID); |
| 286 | BREAK_IF(isCommonShape && !pd::TestOverlap(pd::GetChild(testShape, 0), transform, pd::GetChild(shape, 0), pd::GetTransformation(world, bodyID))); |
| 287 | Body* body = _bodyData[bodyID.get()]; |
| 288 | std::vector<Body*>& results = isCommonShape ? _queryResultsOfCommonShapes : _queryResultsOfChainsAndEdges; |
| 289 | if (body && (results.empty() || results.back() != body)) { |
| 290 | results.push_back(body); |
| 291 | } |
| 292 | } |
| 293 | BLOCK_END |
| 294 | return true; |
| 295 | }); |
| 296 | bool result = false; |
| 297 | for (Body* item : _queryResultsOfCommonShapes) { |
| 298 | if (callback(item)) { |
| 299 | result = true; |
| 300 | break; |
| 301 | } |
| 302 | } |
| 303 | for (Body* item : _queryResultsOfChainsAndEdges) { |
| 304 | if (callback(item)) { |
| 305 | result = true; |
| 306 | break; |
| 307 | } |
| 308 | } |
| 309 | _queryResultsOfCommonShapes.clear(); |
| 310 | _queryResultsOfChainsAndEdges.clear(); |
| 311 | return result; |
| 312 | } |
| 313 | |
| 314 | bool PhysicsWorld::raycast(const Vec2& start, const Vec2& end, bool closest, const std::function<bool(Body*, const Vec2&, const Vec2&)>& callback) { |
| 315 | AssertUnless(_world, "accessing invalid physics world."); |
nothing calls this directly
no test coverage detected