система частиц: генерация частиц

У меня есть система, которая генерирует частицы из источников и обновляет их позиции. В настоящее время я написал программу в OpenGL, которая вызывает мои GenerateParticles(...) и UpdateParticles(...) и отображает мой вывод. Я хотел бы, чтобы моя система могла генерировать n частицы в секунду. В моих функциях GenerateParticles(...) и UpdateParticles(...) я принимаю 2 важных параметра: current_time и delta_time. В UpdateParticles(...) я обновляю позицию своей частицы по следующей формуле: new_pos = curr_pos + delta_time*particle_vector. Как я могу использовать эти параметры и глобальные переменные (или другие механизмы) для производства n частиц в секунду?


person Myx    schedule 19.04.2010    source источник


Ответы (3)


Вы должны быть осторожны, наивный способ создания частиц заставит вас создавать дробные частицы для низких значений n (вероятно, не то, что вы хотите). Вместо этого создайте переменную-аккумулятор, которая суммируется с вашими значениями delta_time в каждом кадре. Проверьте каждый кадр, чтобы увидеть, сколько частиц вам нужно для создания этого кадра, и вычтите соответствующие количества:

void GenerateParticles(double delta_time) {
  accumulator += delta_time;
  while (accumulator > 1.0 / particles_per_second) {
    CreateParticle(...);
    accumulator -= 1.0 / particles_per_second;
  }  
}

Убедитесь, что вы установили некоторые ограничения, чтобы, если дельта времени велика, вы не создавали миллион частиц одновременно.

person Ron Warholic    schedule 19.04.2010

Количество частиц, испускаемых в кадре, можно вычислить по формуле:

double n = delta_time * frequency
int i = (int)n;
f = n - i;

По сути, вы можете излучать i частиц.

Дробная часть f может накапливаться для последующих кадров. Когда его накапливается больше единицы, вы можете испустить целое число частиц:

f_sum += f;
if (f_sum > 1.0) {
    int j = (int)f_sum;
    f_sum -= j;
    i += j;
}

Однако следующее интересное решение для дробного числа частиц.

Используя генератор псевдослучайных чисел (PRNG), мы можем использовать его, чтобы определить, должна ли испускаться частица:

if (f >= r()) // Assumes r() is a PRNG generating a random value in [0, 1) 
    i++;

Этот подход полезен, когда частота изменяется во времени. И это устраняет необходимость хранения дополнительной переменной.

Еще одна прелесть этого подхода в том, что система частиц будет выглядеть менее однородной. Например, если частота равна 1,5, а дельта-время равна 1, при использовании первого подхода кадры будут испускать последовательность из 1, 2, 1, 2, ... частиц. Второй подход может сломать этот шаблон.

Кроме того, вы можете использовать modf() для извлечения целой и дробной части число с плавающей запятой.

person Milo Yip    schedule 15.11.2012

Вам просто нужно создать n * delta_time частицы в GenerateParticles.

person Troubadour    schedule 19.04.2010
comment
delta_time обычно представляет собой двойное число, меньшее нуля. Предположим, что я не могу создать часть частицы. - person Myx; 20.04.2010
comment
@Myx: я думаю, ты имеешь в виду, что меньше единицы? На самом деле это не проблема, как указал @Ron, хотя проще и быстрее накапливать n * delta_time и сравнивать его с 1.... - person Troubadour; 20.04.2010