?

Log in

No account? Create an account
9 сент, 2007 @ 20:56 Игровой движок 6. Система частиц
Интересны ваши мнения о моем дизайне системы частиц. Можно ли сделать его еще лучше? :) Состоит из следующих участников:

ParticleBase - базовый абстрактный класс для всех видов частиц. Содержит чисто виртуальный метод render().
ParticleLine - частица-линия.
ParticleQuad - частица-картинка.
ParticleSprite - частица-спрайт.

MovingStrategyBase - базовый абстрактный класс для стратегий движения частиц. Содержит единственный, чисто виртуальный метод move().
LinearMS - стратегия линейного движения.
CircularMS - стратегия вращательного движения.
...
[MovingStrategy может хранить всевозможные карты плотности, давления, силы полей, ..., для симуляции турбулентности и всяко разного движения в сложных физических средах.]

DivergingStrategyBase - базовый абстрактный класс для стратегий расхождения (в случае столкновения). Содержит единственный, чисто виртуальный метод diverge().
MechanicalDS - механическое столкновение, обмен импульсами и т.д.
...

ParticleSystem - класс системы частиц. Конструктор имеет вид:
ParticleSystem( const COUNT_TYPE _max_particles_count, MovingStrategyBase* _ms, DivergingStrategyBase* _ds );
Содержит метод move(), из которого вызывается moving_strategy->move() для каждой частицы. В одной системе могут быть объединены разные виды частиц (ParticleLine, ParticleQuad, ParticleSprite).

CollisionChecker - класс, в котором регистрируются все collisionable системы частиц. При вызове CollisionChecker::check_collision() происходит проверка всех частиц всех систем на столкновение друг с другом. Если определено столкновение частиц p1 и p2, то происходит два вызова: DivergingStrategyBase::diverge(p1, p2) и DivergingStrategyBase::diverge(p2, p1). Параметры передаются по значению. [Возможно, стратегию проверки столкновения, основанную на тех или иных критериях, тоже следует вынести в отдельный класс.]

ParticleSpace - класс выражает абстракцию Пространства, в котором рождаются, перемещаются и сталкиваются системы частиц. Он предоставляет методы для создания системы частиц, именно через его интерфейс происходит вся работа с описанными выше классами. И именно ParticleSpace содержит экземпляр класса CollisionChecker. [ParticleSpace также может хранить данные о топологии и структуре пространства. Стены, границы можно будет описать в терминах неподвижных, фиксированных частиц. Системы этих фиксированных частиц также регистрируются в CollisionChecker и участвуют в обработке столкновений.]
topright:
[User Picture Icon]
From:sim0nsays
Date:Сентябрь, 9, 2007 18:14 (UTC)
(Ссылка)
Я думаю, надо прыгать от задач.

На нижнем уровне стоит задача отрисовки. Которая включает отдельно заливку буферов (ибо динамика), и собственно отрисовку. Они обычно в разном месте игрового цикла, поэтому наверное одной функции render недостаточно.
Кроме того, рисуются частицы обычно большими бакетами. Не по одной линии, или спрайту, а всегда максимальным количеством за раз. Причем еще надо думать за сортировку по материалам и прочему. То есть базовый элемент - не одна частица, а бакет частиц.
В зависимости от суровости задачи, interleaving позволяется либо нет. Если позволяется, это потенциально делает рендер гораздо медленнее. Технически делается разбиением одного патикл-бакета на много (возможно, похоже на твой diverge).

На уровне повыше - управление движением патиклов. Хочется либо позволять писать скрипты, либо сложные декларативные поведения. У нас вот был большой XML-file, где можно было рулить кучей параметров. Отмечу, что многое из этого может захотеться считать в шейдере, и тогда хуже обособляется в strategy на CPU.

Хуже того, для различных патиклов параметры движения могут быть разные. Для спрайта - координата и угол вращения, цвет и текстурные координаты. Для патикла-меша - целая матрица. Эти параметры можно либо генерализовать и дать стратегии крутить ими всеми, либо изобретать как тип патикла и стратегия движения будут друг о друге узнавать.

Про коллижены соседних патикл-систем я слышал редко, потому что это очень тяжелые вычисления. Столкнуть тысячу динамических частиц с другой тысячью динамических частиц - серьезная задача. И поди никто не заметит, частицы маленькие. Думаю, надо делать физическое взаимодействие с уровнем и хватит. И необходимые эффекты на частицах (типа искры гаснут в дыме) выражать именно в терминах областей на уровне, а не коллижена частиц.

Резюмируя - подумай, как твой дизайн будет решать перечисленные проблемы.



(Ответить) (Ветвь дискуссии)
[User Picture Icon]
From:xproger
Date:Сентябрь, 9, 2007 19:27 (UTC)
(Ссылка)
Передо мной сейчас стоит вопрос. Как лучше реализовать вращающиеся патиклы?
Сейчас, каждый из патиклов помещается в здоровый буфер и представляет собой 4 вершины находящиеся в одной точке, 4 текстурные координаты этих вершин по которым они растягиваются в нужные стороны, Size и Angle (в радианах) по которым он увеличивается и крутицо.

Итого получаю относительно простой вершинный:
void main(void)
{
	vec2 sa = vec2(cos(gl_MultiTexCoord1.x), sin(gl_MultiTexCoord1.x)) * gl_MultiTexCoord1.y;

	vec4 vOffset = vec4(vec3(mat2(sa, vec2(-sa.y, sa.x)) * gl_MultiTexCoord0.xy, 0.0), 0.0);

	gl_Position = gl_ProjectionMatrix * (gl_ModelViewMatrix * gl_Vertex + vOffset);
	gl_TexCoord[0] = vec4((gl_MultiTexCoord0.xy + 1.0) * 0.5, 0.0, 1.0);
}

gl_MultiTexCoord0 -> текстурные координаты в диапозоне [-1..1]
gl_MultiTexCoord1.x -> Angle
gl_MultiTexCoord1.y -> Size

Все патиклы выводятся за один вызов (DIP). Реально ли ускорить? )
(Ответить) (Ветвь дискуссии)
[User Picture Icon]
From:xproger
Date:Сентябрь, 9, 2007 19:30 (UTC)
(Ссылка)
О, придумал как избавиться от передачи блока текстурных координат по которым патикл "раскрывается" из точки. Для каждой вершины буду задавать Angle = BaseAngle + N * pi/2 (!!!)
(Ответить) (Уровень выше) (Ветвь дискуссии)
[User Picture Icon]
From:virtul
Date:Сентябрь, 10, 2007 06:50 (UTC)
(Ссылка)
Начни с редактора.
(Ответить) (Ветвь дискуссии)
From:(Анонимно)
Date:Сентябрь, 10, 2007 13:12 (UTC)
(Ссылка)
что-то похожее писал
у меня в Java было
были частицы, поверхности и силы - три потомка чисто абстрактного класса AbstractSceneObject
На частицы действуют силы (как -- зависит от сил и параметров частицы)
для частиц проверяется столкновение с частицами и поверхностями
параметры частиц, полей, поверхностей могут меняться по времени
на счет CollisionChecker я тоже думал, но отказался
в отдельном потоке рассчитывал все происходящее, в отдельном отрисовывал
чтобы рисовалось все красиво в "расчетном" потоке формировались "снэпшоты", согласно которым уже и происходило рисование
(Ответить) (Ветвь дискуссии)
[User Picture Icon]
From:deemson
Date:Сентябрь, 17, 2007 15:52 (UTC)
(Ссылка)
Опиши, пожалуйста, в чем фундаментальное различие между ParticleQuad и ParticleSprite?
(Ответить) (Ветвь дискуссии)