Окно программы Snow
Рисунок 14.2. Окно программы Snow
Определение класса системы частиц Snow выглядит следующим образом:
class Snow : public PSystem { public: Snow(d3d::BoundingBox* boundingBox, int numParticles); void resetParticle(Attribute* attribute); void update(float timeDelta); };
ПРИМЕЧАНИЕ
Конструктор получает указатель на структуру данных ограничивающего параллелепипеда и количество частиц, которое должно быть в системе. Ограничивающий параллелепипед определяет объем пространства в котором будет падать снег. Если снежинки выходят за границы этого объема, они воскрешаются с новыми координатами. Таким образом система поддерживает постоянное количество активных частиц. Реализация конструктора выглядит следующим образом:
Snow::Snow(d3d::BoundingBox* boundingBox, int numParticles) { _boundingBox = *boundingBox; _size = 0.8f; _vbSize = 2048; _vbOffset = 0; _vbBatchSize = 512;
for(int i = 0; i < numParticles; i++) addParticle(); }
Обратите внимание, что мы задаем размер буфера вершин, размер партии частиц и начальное смещение.
Метод resetParticle создает снежинку внутри ограничивающего параллелепипеда со случайными значениями координат X и Z, а значение координаты Y делает равным координате верха ограничивающего объема. Затем вектор скорости снежинки устанавливается таким образом, чтобы она падала вниз и при этом слегка смещалась влево. Помимо этого, снежинка окрашивается в белый цвет:
void Snow::resetParticle(Attribute* attribute) { attribute->_isAlive = true;
// Получить случайные значения координат X и Z снежинки d3d::GetRandomVector( &attribute->_position, &_boundingBox._min, &_boundingBox._max);
// Для высоты (координаты Y) случайное значение не нужно. // Падение снежинок всегда начинается с верха // ограничивающего параллелепипеда attribute->_position.y = _boundingBox._max.y;
// Снежинка падает вниз и слегка смещается влево attribute->_velocity.x = d3d::GetRandomFloat(0.0f, 1.0f) * -3.0f; attribute->_velocity.y = d3d::GetRandomFloat(0.0f, 1.0f) * -10.0f; attribute->_velocity.z = 0.0f;
// Все снежинки белые attribute->_color = d3d::WHITE; }
Метод update обновляет местоположение частиц, а затем проверяет не вышли ли какие-нибудь частицы за пределы ограничивающего объема системы. Если частица вышла за пределы ограничивающего параллелепипеда, она заново инициализируется и снова падает с самого верха.
void Snow::update(float timeDelta) { std::list<Attribute>::iterator i; for(i = _particles.begin(); i != _particles.end(); i++) { i->_position += i->_velocity * timeDelta;
// Точка вне ограничивающего объема? if(_boundingBox.isPointInside(i->_position) == false) { // Вышедшие за пределы объема частицы не // уничтожаются, а снова используются и // воскрешаются с новыми координатами resetParticle(&(*i)); } } }