Boids getting stuck - Chapter 17

I noticed on from the “cohesion” part of Chapter 17 that my boids would eventually all get stuck on the top and left edges of the window, and they’re doing that in the supplied “final” project also. I’ve been trying to figure out why that is and I think it might have to do with the way the bounds-checking occurs:

if (position.x < 0 || position.x > output.get_width()) { velocity.x *= -1; }

Doesn’t this (and the accompanying “y” adjustment) cause problems by making this change after the velocity accumulation? Like, if the cohesion factor is going to drive an near-or-out-of-bounds boid back towards the group, then the bounds check is reversing that velocity and driving it away from the group and further out-of-bounds, no? And I think that’s why they’re getting stuck, but I can’t see why I’m only seeing the stuck behavior on the top and left edges (wouldn’t this apply to all edges?). So I’ve kind of fixed it by replacing it with:

if ((position.x + velocity.x) < 0 || (position.x + velocity.x) > output.get_width()) { velocity.x *= -1; }

but of course that’s not synonymous with the intended behavior - this makes them “anticipate” going out of bounds instead of strictly bouncing off the edge. Thoughts? Anyone able to recreate the problem? (I have to let the final project run for a minute but within a few minutes they’re all stuck).

Anyway, I think there’s a mistake in the boid-thickening:

output.write(color, location + uint2(-1, 1)); output.write(color, location - uint2(-1, 1)); output.write(color, location + uint2(1, -1)); output.write(color, location - uint2(1, -1));

These are two accidentally synonymous pairs, aren’t they? i.e. +(-1,1) and -(1,-1) are the same. Should be +(-1,1), -(-1,1), +(1,1), -(1,1). Yer birds are accidentally oblong instead of beautiful perfectly square birds like nature intended.

(i see my code line breaks aren’t showing … how do i fix that?)

I’m wondering if it’s intentional that attenuation is applied to dampening twice, both within the dampening function and within secondpass … it seems like dampening would always be one hundredth, then, which doesn’t seem like much compared to the default limit of 20?

@caroline Can you please help with this when you get a chance? Thank you - much appreciated! :]

I think they are, as you say, getting stuck at the edges. So if a significant mass gets stuck, the whole boid group will get stuck.

I fixed it with having a threshold before changing velocity.

I added a threshold to boid and changed the velocity shader code to:

  if (position.x < 0 || position.x > output.get_width()) {
    if (boid.threshold.x <= 0) {
      velocity.x *= -1;
      threshold.x = 50;
    } else {
      threshold.x--;
    }
  }
  
  if (position.y < 0 || position.y > output.get_height()) {
    if (boid.threshold.y <= 0) {
      velocity.y *= -1;
      threshold.y = 50;
    } else {
      threshold.y--;
    }
  }

That means that they are shy of the edges, and enough of them stay away so they don’t get stuck.