Вы всегда возвращаете (в основном) одно и то же направление при каждом вызове cohesion
, поэтому вы устанавливаете для всех m->acc
одинаковое значение.Это потому, что ваш return
in cohesion
уже выходит на первый бой.
Проблема в том, что вы не определились с тем, что cohesion
должен делать.Если предполагается вернуть целевое направление один boid, то вы должны указать ему , что boid следует учитывать.Вы также можете обновить m->acc
непосредственно в cohesion
и просто оставить updateBoid
, чтобы изменить m->pos
(и только читать m->acc
- это, вероятно, лучшее решение.
В коде:
Вариант 1: ничего не возвращать. Изменять только каждую единицу. Не вызывать cohesion
внутри updateBoid
, только один раз.
void Scene::updateBoid()
{
for(size_t i=0; i<m_collection.size(); ++i)
{
for(auto &m :m_collection[i])
{
float acc = m->dir;
m->pos += acc * 0.05f;
}
}
}
void Scene::updateCohesion()
{
for(size_t i=0; i<m_collection.size(); ++i)
{
// This must be in here, otherwise it will be slightly wrong later.
Vec3 center;
for(auto _m :m_collection[i]) // all of the boids
{
center += _m->pos;
}
center /= m_collection[i].size(); // doing this gives the center
/// Boids move to the center of their average positions
for(auto &m :m_collection[i])
{
m->dir =center - m->pos; //vector between the two objects
m->dir.normalize();
}
}
}
Вариант 2: вернуть направление для каждой единицыЭто неэффективно, потому что вы вычисляете центр снова каждый раз.
void Scene::updateBoid()
{
for(size_t i=0; i<m_collection.size(); ++i)
{
for(auto &m :m_collection[i])
{
float acc = cohesionForBoid(m_collection[i], m);
m->pos += acc * 0.05f;
}
}
}
// What are these types? We don't know, that is missing from the question.
Vec3 Scene::cohesionForBoid(??? collection, ??? m)
{
Vec3 center;
for(auto _m : collection) // all of the boids
{
center += _m->pos;
}
center /= collection.size(); // doing this gives the center
Vec3 dir = center - m->pos; //vector between the two objects
dir.normalize();
return dir;
}