Рисунок 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::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;