forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Организация системы частиц (http://forum.boolean.name/showthread.php?t=14707)

Vadimich 10.05.2011 20:51

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

Помогите пожалуйста правильно организовать вышеупомянутую.
я уже как-то писал такое, но использовал в качестве частиц отдельные спрайты... понимаю, что это изврат. читал где-то, что намного быстрее - использовать вместо отдельных Entity квады, объедененные в один Mesh, но как это сделать ума не приложу :( т.е. вроде создавать сёрфейсы у меня получается, но в каком массиве хранить идентификаторы каждого квада и их индивидуальные параметры, правильно трансформировать.
вот набросал небольшой примерчик (ниже). Не могли бы вы сделать его аналог с использованием объедененных квадов. Буду очень признателен за помощь

-----------------------Example:
Graphics3D 800,600,32,2
SetBuffer BackBuffer()

cam = CreateCamera(): PositionEntity cam,0,0,-15
t = CreateTimer(60)

EmitterCreate (0,0,20) ; создание Эмиттера


Repeat
WaitTimer(t)



EmitterUpdate(); Обновление Эмиттера

UpdateWorld
RenderWorld

Flip(0)

Until KeyHit(1)
End

;================================================= ===================Functions

Type Emitter
Field interval, timer
Field x#, y#
Field entity
End Type

Type particle
Field entity
Field speed#
Field turn#
Field alpha#
End Type

Function EmitterCreate (x,y, interval)
e.Emitter = New Emitter
e\interval = interval
e\timer = e\interval
e\x = x
e\y = y
e\entity = CreateSprite(): SpriteViewMode e\entity,2: EntityAlpha e\entity,.5 ; создаем простенький эмиттер
End Function

Function EmitterUpdate ()
For e.Emitter = Each Emitter

; запуск частиц
e\timer = e\timer+1
If e\timer>e\interval
;================================================= ===================
p.particle = New particle
p\speed# = .1
p\turn = 1
p\alpha = .5
p\entity = CreateSprite(): SpriteViewMode p\entity,2
PositionEntity p\entity,e\x, e\y,0: RotateEntity p\entity, 0,0,EntityRoll (e\entity)
EntityAlpha p\entity,p\alpha
e\timer = 0
;================================================= ===================
EndIf

;обновление частиц
;================================================= ===================
For p.particle = Each particle
p\turn = p\turn+2
MoveEntity p\entity,0,p\speed,0
RotateSprite p\entity,p\turn
Next

Next
End Function

LLI.T.A.L.K.E.R. 11.05.2011 00:22

Ответ: Организация системы частиц
 
Не рекомендуется иметь в цикле:
Цитата:

p.particle=New particle
p\entity = CreateSprite()
Намного экономичней CopyEntity (Глобал_Спрайт или Эмитер_Спрайт)

А не легче изучить готовые партикл системы?
(передумал написать "а не легче использовать...")

Vadimich 11.05.2011 08:19

Ответ: Организация системы частиц
 
Спасибо. это был маленький примерчик. в уже готовой есть функция копирования ентити (SetReference (Entity) )
просто я хочу серьезно расширить функционал уже существующей.. но если уж переписывать столько кода, то уж сразу делать это правильно... CopyEntity ведь наверное тоже не экономичнее созданного полика и добавленного к одной сетке? а чем быстрее она будет работать, тем больше частиц можно будет генерить.

EvilChaotic 11.05.2011 10:00

Ответ: Организация системы частиц
 
Цитата:

Сообщение от LLI.T.A.L.K.E.R. (Сообщение 188083)
А не легче изучить готовые партикл системы?

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

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

Камерра
Global Un_SinglesurfaceParticleSys_Camera
Максимум партиклов в системе
Const Un_SinglesurfaceParticleSys_MaxParticle = 100

Тип системы
Код:

Type Un_SinglesurfaceParticleSys_Emitter
        Field Mesh
                Field Surface
                ; - Texture
                Field Particles[Un_SinglesurfaceParticleSys_MaxParticle]
                Field ParticleCount
End Type

Тип квада
Type Un_SinglesurfaceParticleSys_Particle
        Field Surface
                ; Vertex Index
                Field v_In[3]
                ; 0 - Current coords 1 - Dest Coords 2 -StandartCoords
                Field x,y,z#
End Type

Создание системы
Function Un_SinglesurfaceParticleSys_CreateEmitter()
        Un_sse.Un_SinglesurfaceParticleSys_Emitter = New Un_SinglesurfaceParticleSys_Emitter
                Un_sse\Mesh = xCreateMesh()
                        Un_sse\Surface = xCreateSurface(Un_sse\Mesh)
                        xEntityFX Un_sse\Mesh,1+2+8
        Return Handle(Un_sse)
End Function

Апдейт системы
Function Un_SinglesurfaceParticleSys_Update()
        For Un_sse.Un_SinglesurfaceParticleSys_Emitter = Each Un_SinglesurfaceParticleSys_Emitter
                For i = 0 To Un_sse\ParticleCount - 1
                        Un_SinglesurfaceParticleSys_UpdateParticle(Un_sse\Particles[i])
                Next
End Function

Добавить квад в систему
Function Un_SinglesurfaceParticleSys_AddParticle(h)
        Un_sse.Un_SinglesurfaceParticleSys_Emitter = Object.Un_SinglesurfaceParticleSys_Emitter(h)
                For i = 0 To Un_SinglesurfaceParticleSys_MaxParticle - 1
                        If Un_sse\Particles[i] = 0
                                Un_sse\Particles[i] = Un_SinglesurfaceParticleSys_CreateParticle(Un_sse\Surface) : Exit
                        End If
                Next
                Un_sse\ParticleCount = Un_sse\ParticleCount + 1
                Return Un_sse\Particles[i]
End Function

Описание создание квада
Function Un_SinglesurfaceParticleSys_CreateParticle(surface)
        Un_ssp.Un_SinglesurfaceParticleSys_Particle = New Un_SinglesurfaceParticleSys_Particle
                Un_ssp\Surface = surface
                Un_ssp\v_In[0] = xAddVertex(Un_ssp\Surface, 0, 0, 0, 0, 1)
                Un_ssp\v_In[1] = xAddVertex(Un_ssp\Surface, 0, 0, 0, 1, 1)
                Un_ssp\v_In[2] = xAddVertex(Un_ssp\Surface, 0, 0, 0, 0, 0)
                Un_ssp\v_In[3] = xAddVertex(Un_ssp\Surface, 0, 0, 0, 1, 0)
                        xAddTriangle(Un_ssp\Surface, Un_ssp\v_In[1], Un_ssp\v_In[2], Un_ssp\v_In[3])
                        xAddTriangle(Un_ssp\Surface, Un_ssp\v_In[2], Un_ssp\v_In[1], Un_ssp\v_In[0])
                        ; - Set Param
                        Un_ssp\Scale#= 1.0
                        Un_ssp\x# = Rnd(-3,3) : Un_ssp\y# = Rnd(-3,3) : Un_ssp\z# = Rnd(-3,3)
                Return Handle(Un_ssp)
End Function

Ну и апдейт квада, поворачиваем его на камеру.
Function Un_SinglesurfaceParticleSys_UpdateParticle(h)
        Un_ssp.Un_SinglesurfaceParticleSys_Particle = Object.Un_SinglesurfaceParticleSys_Particle(h)

                        xTFormVector -Un_ssp\Scale#,-Un_ssp\Scale#,0,Un_SinglesurfaceParticleSys_Camera,0
                        xVertexCoords Un_ssp\Surface,Un_ssp\v_In[0],Un_ssp\x+xTFormedX#(),Un_ssp\y+xTFormedY#(),Un_ssp\z+xTFormedZ#()
                       
                        xTFormVector Un_ssp\Scale#,-Un_ssp\Scale#,0,Un_SinglesurfaceParticleSys_Camera,0
                        xVertexCoords Un_ssp\Surface,Un_ssp\v_In[1],Un_ssp\x+xTFormedX#(),Un_ssp\y+xTFormedY#(),Un_ssp\z+xTFormedZ#()

                        xTFormVector -Un_ssp\Scale#,Un_ssp\Scale#,0,Un_SinglesurfaceParticleSys_Camera,0
                        xVertexCoords Un_ssp\Surface,Un_ssp\v_In[2],Un_ssp\x+xTFormedX#(),Un_ssp\y+xTFormedY#(),Un_ssp\z+xTFormedZ#()

                        xTFormVector Un_ssp\Scale#,Un_ssp\Scale#,0,Un_SinglesurfaceParticleSys_Camera,0
                        xVertexCoords Un_ssp\Surface,Un_ssp\v_In[3],Un_ssp\x+xTFormedX#(),Un_ssp\y+xTFormedY#(),Un_ssp\z+xTFormedZ#()

End Function

Код:

Un_SinglesurfaceParticleSys_Camera = твоя камера

e = Un_SinglesurfaceParticleSys_CreateEmitter()
for i = 0 to 9
    p = Un_SinglesurfaceParticleSys_AddParticle(e)
next

В цикл
Un_SinglesurfaceParticleSys_Update()

Далее функции ротации и перемещения и скейла.
Перемещения можно сделать, прибавив вектор
x = x + x1
y = y + y1
z = z + z1

Ротация
Это sin/cos со scale и углом.

Скейл
Это просто установить к переменной в типе Scale любое значение.

Дз будет привести это в божеский вид и сделать функции управления. Делал код почти в форуме так что не тестил.

Артем Валерьевич 11.05.2011 10:38

Ответ: Организация системы частиц
 
не понял как вращать всётаки, а вернее что вращать?

Vadimich 11.05.2011 11:48

Ответ: Организация системы частиц
 
EvilChaotic Спасибо огромное за то что уделил столько времени! сейчас работу разгребу и буду разбираться с этим всем :) Я тоже считаю, что подобный опыт просто необходим

Vadimich 11.05.2011 15:05

Ответ: Организация системы частиц
 
а есть ли возможность создавать эмиттеры с индивидуальным максимальным количеством частиц.. скажем, один эмиттер испускает дым, другой искры а третий - выбрасывает гильзы или делает всплески.. для них для всех требуются разные значения.. если для брызг может доходить до десятков, то для гильз достаточно и нескольких штук. Стоит ли задумываться о экономии размеров массивов, если одновременно на экране будет десяток эмиттеров или это экономия на спичках?

tormoz 11.05.2011 19:39

Ответ: Организация системы частиц
 
http://tv-kom.com/particle_AMT_full.rar

L.D.M.T. 11.05.2011 21:28

Ответ: Организация системы частиц
 
таки подключил амт частицы, но на фоне такой графики они смотрятся как-то убого... попробую подставить сюда еще и аним-спрайты с настоящим огнем.

http://myblitz3d.nextmail.ru/temp/fire.jpg

Vadimich 11.05.2011 21:28

Ответ: Организация системы частиц
 
Спасибо!
протестил квады по сравнению с entity - прирост производительности экстримальный! извините, если вопрос совсем уж невежественный, но как квадам, относящимся к одному surface одного mesh'a сделать разную прозрачность?

HolyDel 11.05.2011 22:32

Ответ: Организация системы частиц
 
задавать альфу вершинам

использовать EntityFX, 32 кажется

Vadimich 12.05.2011 12:29

Ответ: Организация системы частиц
 
А несколько сотен (или тысяч) пустых ячеек(не занятых частицами) в массиве[ ] погоды не делают? Просто мне однажды кто-то посоветовал использовать как можно меньше массивов.. вот и парюсь теперь :(

Taugeshtu 12.05.2011 12:47

Ответ: Организация системы частиц
 
Ну смотри, грубо говоря частица, на самом деле хранимая в том массиве - это не частица, а ссылка на неё (соответсвенно, Null если ссылки нет). Я могу конечно сильно ошибаться, но думаю, это так. Далее, ссылка - это 32 бита информации. Представим, что у тебя в стандартном таком массиве 1000 частиц (не зависимо от того, сколько их на самом деле). Тогда это 4кБ инфы. А теперь подумай, насколько много у тебя должно быть систем частиц единовременно, на какую оперативную память ты рассчитываешь и стоит ли париться.

Если я не прав на счёт ссылок, и в массиве действительно хранится элемент типа частицы, то навскидку кол-во инфы в таком типе:
x,y,z + то же самое для углов и масштабов = 9 float (а флоаты в б3д = 32 бита)
ещё 4 флоата - для цвета в формате RGBA (если по-хорошему (нужна избыточная инфа для HDR, но я не могу себе представить такую необходимость в б3д), по-плохому-то там и одного флоата достаточно :-D)

Ещё флоат - время жизни частицы

Ещё 3 флоата - направление перемещения от предыдущего шага (зная его, удобнее делать всякие спиральные траектории для, допустим, искр от костра) - ну это уже опция.

Итого в средне-гнущихся партиклах мы получаем... 14 флоат-переменных, что равно 14*4 = 56 байт на партикл. Опять же, 1000 партиклов ~ 56 кБ инфы в памяти.

Если у тебя конечно по 10000 партиклов в системе, да ещё самих систем частиц "хорошо за 100" - то это уже серьёзно, 56 МБ памяти на частицы. Но если это не так - я бы не заморачивался.

Vadimich 12.05.2011 12:51

Ответ: Организация системы частиц
 
я думаю, Ты прав.. первый случай вернее.. ведь если ячейка не занята, то в ней нет не ссылки на экземпляр типа, ни других параметров вроде времени жизни, размера, скорости.. т.к. они должны храниться в самом экземпляре. Спасибо :)

Vadimich 12.05.2011 16:07

Ответ: Организация системы частиц
 
хм.. а как удалить квад? не думал, что с этим будут проблемы, но команды я такой ещё не нашел.. clearSurface удаляет всё, а нужно снести только 2 треугольника


Часовой пояс GMT +4, время: 08:31.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot