| 28 | } |
| 29 | |
| 30 | void ParticleManager::update(float dt, RectF const& cullRegion, float wind) { |
| 31 | if (!m_tileSectorArray) |
| 32 | return; |
| 33 | |
| 34 | auto cullRects = m_worldGeometry.splitRect(cullRegion); |
| 35 | |
| 36 | for (auto& particle : m_particles) { |
| 37 | bool inRegion = false; |
| 38 | Vec2F worldPos = m_worldGeometry.xwrap(particle.position); |
| 39 | for (auto cullRect : cullRects) { |
| 40 | if (cullRect.contains(worldPos)) { |
| 41 | inRegion = true; |
| 42 | break; |
| 43 | } |
| 44 | } |
| 45 | if (!inRegion) |
| 46 | continue; |
| 47 | |
| 48 | particle.update(dt, Vec2F(wind, 0)); |
| 49 | Vec2I pos(particle.position.floor()); |
| 50 | TileType tiletype; |
| 51 | auto const& tile = m_tileSectorArray->tile(pos); |
| 52 | if (isSolidColliding(tile.getCollision())) |
| 53 | tiletype = TileType::Colliding; |
| 54 | else if (tile.liquid.level > 0.5f) |
| 55 | tiletype = TileType::Water; |
| 56 | else |
| 57 | tiletype = TileType::Empty; |
| 58 | |
| 59 | if (particle.collidesForeground && tiletype == TileType::Colliding) { |
| 60 | RectF colRect; |
| 61 | colRect.setXMax(std::ceil(particle.position[0])); |
| 62 | colRect.setXMin(std::floor(particle.position[0])); |
| 63 | colRect.setYMax(std::ceil(particle.position[1])); |
| 64 | colRect.setYMin(std::floor(particle.position[1])); |
| 65 | Line2F colLine(particle.position, particle.position - particle.velocity); |
| 66 | |
| 67 | auto collisionPosition = colRect.edgeIntersection(colLine).point; |
| 68 | if (particle.position[0] > colRect.center()[0]) |
| 69 | collisionPosition[0] += 0.1f; |
| 70 | else if (particle.position[0] < colRect.center()[0]) |
| 71 | collisionPosition[0] -= 0.1f; |
| 72 | if (particle.position[1] > colRect.center()[1]) |
| 73 | collisionPosition[1] += 0.1f; |
| 74 | else if (particle.position[1] < colRect.center()[1]) |
| 75 | collisionPosition[1] -= 0.1f; |
| 76 | |
| 77 | particle.collide(collisionPosition); |
| 78 | } |
| 79 | |
| 80 | if (particle.underwaterOnly && tiletype == TileType::Empty) |
| 81 | particle.destroy(false); |
| 82 | |
| 83 | if (particle.collidesLiquid && tiletype == TileType::Water) |
| 84 | particle.destroy(false); |
| 85 | |
| 86 | if (particle.trail && particle.timeToLive >= 0.0f) { |
| 87 | auto trail = particle; |
nothing calls this directly
no test coverage detected