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 треугольника

Taugeshtu 12.05.2011 16:52

Ответ: Организация системы частиц
 
Не помню тонкостей именно б3д, в общем случае алгоритм такой:
  1. берём вертекс буффер в массив;
  2. удаляем из массива ненужные вершины;
  3. то же самое делаем с индекс буффером;
  4. присваиваем сурфейсу обратно вершинный и индексный буфферы.

Здесь же пожно сделать маленький хак - не удалять вертексы, а помечать их как удалённые, полностью скрывать, а когда потребуется - призывать в другом месте. Способы скрывания - от альфы вершин до переноса координат вершин в далекие края.

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

P.S.
Пора мне завязывать со вложенными мыслями... Жалко нельзя в формате MindMap ответы писать))

tormoz 12.05.2011 18:30

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

Сообщение от L.D.M.T. (Сообщение 188136)
таки подключил амт частицы, но на фоне такой графики они смотрятся как-то убого... попробую подставить сюда еще и аним-спрайты с настоящим огнем.

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

при чем тут огонь из примера сделанный за 2 минуты из подножных картинок ?
сделай свой эмиттер из своей медии

HolyDel 12.05.2011 18:33

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

Vadimich 15.05.2011 19:07

Ответ: Организация системы частиц
 
Спасибо большое всем за содействие. Ваша помощь дала мне хорошего пинка в работе :)

ІГРОГРАЙКО 29.05.2011 16:01

Ответ: Организация системы частиц
 
Вложений: 1
Привет всем!

Есть вопрос о количестве загружаемых частиц...
У меня на компе получилось создать максимум = 13824
Вложение 13869

Вот код:
Код:

Graphics3D 640,480,32,2
SetBuffer BackBuffer()

Global spr

For z=0 To 24
        For y=0 To 24
                For x=0 To 24
                        spr=CreateSprite()
                        EntityAlpha spr,Rnd(0.05,0)
                        PositionEntity spr,x,y,z
                Next
                Write "|"
        Next
        Print
Next

cam=CreateCamera()
PositionEntity cam,0,10,-20

While Not KeyHit(1)

MoveEntity cam,3,0,0
PointEntity cam,spr

RenderWorld

Flip
Wend
End

У кого больше?
Возможно ли вопше создать больше, а если да то как?

LLI.T.A.L.K.E.R. 29.05.2011 16:10

Ответ: Организация системы частиц
 
Примерно как-то так:
http://www.forum.boolean.name/showpo...9&postcount=52


Спрайты самые лаговые.
Лучше использовать Квады и AddVertex / AddTriangle / AddMesh

Уважаемый ABTOMAT это делал в world.bb, Function buildSide(

ІГРОГРАЙКО 29.05.2011 16:15

Ответ: Организация системы частиц
 
Да спасибо... Я понял что ето возможно...
Если я создаю массив частиц хотя бы (25х24х24) - вилетает Memory access violation

...

Попробую тогда квадами...

HolyDel 30.05.2011 19:17

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

У меня на компе получилось создать максимум = 13824
блиц не сдох штоль на таком количестве дипов? или тебе не реалтайм?

ІГРОГРАЙКО 31.05.2011 01:47

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

Сообщение от HolyDel (Сообщение 189871)
блиц не сдох штоль на таком количестве дипов? или тебе не реалтайм?

Нет, не сдох как видно на скрине и работает в realtime правда всего 5-10 fps... А чьо? вот кода 24*24*25 тогда дохнет... :rolleyes:

HolyDel 31.05.2011 18:02

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

работает в realtime правда всего 5-10 fps..
вот ето я и называю сдох.



вот тут 100 х 100 х 100 спрайтов:
http://axelynx.googlecode.com/files/Hypercube.zip

правдо надо DX10 железо((

Nex 02.06.2011 09:01

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

Ну и апдейт квада, поворачиваем его на камеру.
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_ss p\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_ss p\z+xTFormedZ#()

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

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

End Function
Как то не правильно функция работает. Квады превращаются в треугольники..
Переставил "-" у "Un_ssp\Scale#" и с первым вертексом что то не то, но остальные нормально на камеру разворачиваются. :(

Nex 05.06.2011 17:44

Ответ: Организация системы частиц
 
Как вращать вертексы квада? С Sin и Cos получается совсем не то. :(

maxturbo 05.06.2011 23:13

Ответ: Организация системы частиц
 
Вложений: 5
Попробовал сделать огонь в Particle AMT :) Вроде не плохо получается... :)

aleksxxxl 15.08.2011 23:21

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

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

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

И всё же как нормально настроить ротацию, может кто сможет объяснить?
Пробывал играться с синусами и косинусами и скейлом в итоге ротацию настроил, но стоит только привязать квад ТФормВектор к камере так квад начинает беспорядочно крутиться в разные стороны... в общем не получается.:(
Сделал ротацию текстуры, но это не выход, т.к. текстура вертится на всех квадах одинакого, а это совсем не гуд :(

В системе частиц которую выложил Tormoz не пашет редактор под windows 7, хоть и можно конечно переписать функцию LoadEmitter в CreateEmitter :) , но если честно то хочется свою систему частиц в которой я как рыба в воде, но вот беда ротацию никак не настрою с ориентацией квада на камеру!

dsd 16.08.2011 00:05

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

Условие перпендикулярности векторов (x1*x2+y1*y2+z1*z2)=0
Третий вектор перпендикулярный двум данным получается векторным умножением. И вот у тебя есть точка и два вектора. Позиции четырех вершин. 0 - у меня это была опорная точка, через которую проводились все манипуляции с квадом, как его перемещение, масштабирование и вращение. 1 - 0+первый вектор, 2-0+второй вектор, 3-0 плюс вектор1+вектор 2. Профит. Поворот тоже несложен. Если мыслить правильно и векторами, а не тригонометрией :) Потому как расчитать длину второго катета, шоб гипотенуза повернулась на угол от первого катета несложно, а направляющие векторы катетов у тебя есть :)

Результат моих попыток квадов, вроде даже работает почти :) Тут я правда синусами делал :) Этот прием называется поворот осей координат.
Код:

Graphics3D 640,480,0,2
SetBuffer BackBuffer()
SeedRnd=MilliSecs()
Dither 0

Global pivot,camera,mxs#,mys#,Light,timer3
Dim quadsys#(1,1)

pivot=CreatePivot()
PositionEntity pivot,0,3,-10
camera=CreateCamera(pivot)
CameraClsColor camera,0,75,151
light=CreateLight()
MeshLight=CreateSphere(6,light)
ScaleMesh meshlight,2.3,2.3,2.3
EntityFX meshlight,1
AmbientLight 15,15,15
mz=CreateQuadSystem(600)
FillArray(mz)


While Not ((KeyDown(56) And KeyHit(62)) Or  (KeyHit(56) And KeyDown(62))  Or KeyHit(1))
timer3=MilliSecs()
PointEntity light,camera
PositionEntity light,125*Sin(MilliSecs()/30),125,125*Cos(MilliSecs()/30)


QuadroFlipper(camera,mz)
updatearray(mz)


UpdateWorld
RenderWorld
control(0.5,1.4)
Flip 0
Wend
End

Function UpdateArray(quadsystem)

mesh=quadsystem
meshsurf=GetSurface(mesh,1)
qverts=CountVertices(meshsurf)/4

For i=0 To qverts-1
quadsys#(i,1)=quadsys#(i,1)-0.2
quadsys#(I,5)=MilliSecs()/10+i
If quadsys#(i,1)<0 Then
quadsys#(i,0)=Rnd(-60,60)        ;        x position
quadsys#(i,1)=120                                                                        ;        y position
quadsys#(i,2)=Rnd(-60,60)        ;        z position

EndIf
Next
End Function

Function FillArray(quadsystem)
mesh=quadsystem
meshsurf=GetSurface(mesh,1)
qverts=CountVertices(meshsurf)/4
Dim quadsys#(qverts,14)
;        0-xcoord
;        1-ycoord
;        2-zcoord
;        3-widthscale
;        4-heightscale
;        5-rotate
;        6-timer uno
;        7-timer two
;        8-for bright future
;        9-just for fun
;        10-sucriface to gods
;        11-reserved x
;        12-reserved y
;        13-reserved z


For i=0 To qverts-1

quadsys#(i,0)=VertexX(meshsurf,i*4)        ;        x position
quadsys#(i,1)=VertexY(meshsurf,i*4)                ;        y position
quadsys#(i,2)=VertexZ(meshsurf,i*4)                ;        z position
quadsys#(i,3)=Rnd(1,3)                                                        ;        width scale
quadsys#(i,4)=Rnd(1,3)                                                        ;        height scale
quadsys#(i,5)=Rnd(0,359.99)                                        ;        angle of rotate
quadsys#(i,11)=VertexX(meshsurf,i*4)        ;        x position
quadsys#(i,12)=VertexY(meshsurf,i*4)                ;        y position
quadsys#(i,13)=VertexZ(meshsurf,i*4)                ;        z position

Next
End Function



Function QuadroFlipper(srcobj,quadsystem)

aim=srcobj
mesh=quadsystem
meshsurf=GetSurface(mesh,1)
qvert=CountVertices(meshsurf)-1
For number=4 To qvert-1 Step 4
v0=number
v1=v0+1
v2=v0+2
v3=v0+3

x0#=quadsys#(number/4,0)
y0#=quadsys#(number/4,1)
z0#=quadsys#(number/4,2)
sw#=quadsys#(number/4,3)
sh#=quadsys#(number/4,4)
ar#=quadsys#(number/4,5)
TFormPoint x0,y0,z0,mesh,aim

TFormNormal  TFormedX(),TFormedY(),TFormedZ(),aim,aim
a#=TFormedX()
b#=TFormedY()
c#=TFormedZ()

a1#=Cos(ACos(a)-90)
x01#=a1*Cos(ar)+b*Sin(ar)
y01#=b*Cos(ar)+a1*Sin(ar)
z01#=c*Cos(ar)

b2#=Cos(ACos(b)+90)
x02#=a*Cos(-ar)+b2*Sin(-ar)
Y02#=b2*Cos(-ar)+a*Sin(-ar)
z02#=c*Cos(ar)

TFormVector x01,y01,z01,aim,mesh

vx1#=TFormedX()*sw
vY1#=TFormedY()*sw
vZ1#=TFormedZ()*sw

TFormVector x02,y02,z02,aim,mesh

vx2#=TFormedX()*sh
vY2#=TFormedY()*sh
vZ2#=TFormedZ()*sh


VertexCoords meshsurf,v0,x0,y0,z0
VertexCoords meshsurf,v1,x0+vx1,y0+vy1,z0+vz1
VertexCoords meshsurf,v2,x0+vx2,y0+vy2,z0+vz2
VertexCoords meshsurf,v3,x0+vx1+vx2,y0+vy1+vy2,z0+vz1+vz2
;it's more faster and accurate  than updatenormals
VertexNormal meshsurf,v0,vx2,vy1,vyz2
VertexNormal meshsurf,v1,vx2,vy1,vyz2
VertexNormal meshsurf,v2,vx2,vy1,vyz2
VertexNormal meshsurf,v3,vx2,vy1,vyz2
Next
;UpdateNormals mesh


End Function


Function CreateQuadSystem(number)
mesh=CreateMesh()
meshsurf=CreateSurface(mesh)

For i=0 To number
x1#=Rnd(-60,60)
y1#=Rnd(0,120)
z1#=Rnd(-60,60)
v0=AddVertex(meshsurf,x1,y1,z1,0,0)
v1=AddVertex(meshsurf,x1+1,y1,z1,0,1)
v2=AddVertex(meshsurf,x1,y1+1,z1,1,0)
v3=AddVertex(meshsurf,x1+1,y1+1,z1,1,1)

AddTriangle(meshsurf,v0,v1,v2)
AddTriangle(meshsurf,v3,v2,v1)

Next
UpdateNormals Mesh


testtex=CreateTexture(256,256,256)
SetBuffer TextureBuffer(testtex)
Color 127,127,127
Rect 0,0,128,128
Rect 128,128,128,128
Color 235,240,235
Rect 0,128,128,128
Rect 128,0,128,128
SetBuffer BackBuffer()
EntityTexture mesh,testtex,0,0


pltex=CreateTexture(256,256,256)
SetBuffer TextureBuffer(pltex)
Color 27,27,27
Rect 0,0,128,128
Rect 128,128,128,128
Color 127,127,127
Rect 0,128,128,128
Rect 128,0,128,128
SetBuffer BackBuffer()
ScaleTexture pltex,80,80
plane=CreatePlane()
EntityTexture plane,pltex

Return mesh

End Function


Function control(speed#,mousesensitivity#)
If KeyDown(2) WireFrame True Else WireFrame False
mxs#=mxs#+(MouseXSpeed()/5.0)
mys#=mys#+(MouseYSpeed()/5.0)
RotateEntity camera,mousesensitivity#*mys#,-mousesensitivity#*mxs#,0
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
If KeyDown(17) Or KeyDown(200) MoveEntity camera,0,0,speed#
If KeyDown(31) Or KeyDown(208) MoveEntity camera,0,0,-speed#
If KeyDown(30) Or KeyDown(203) MoveEntity camera,-speed#,0,0
If KeyDown(32) Or KeyDown(205) MoveEntity camera,speed#,0,0
PositionEntity pivot,EntityX#(camera,1),EntityY#(camera,1),EntityZ#(camera,1)
PositionEntity camera,0,0,0


Text 100,10,"polygons in view "+TrisRendered()
If (MilliSecs()-timer3)<>0 Text 100,40,"Frames per second is: "+1000/(MilliSecs()-timer3)
End Function


aleksxxxl 16.08.2011 00:54

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

dsd 16.08.2011 01:18

Ответ: Организация системы частиц
 
Тогда минусуй половинки векторов, 0 точка дальше также.

Векторы это проще тригонометрии. Я вообще имею желание линчевать того кто придумал преподавать в школе тригонометрию и бэсик.

Исчо математики :)
По теоремме толи пифагора толи архимеда, длина вектора: d=sqr(x1^2+y1^2+z1^2), единичный вектор (x1/d,y1/d,z1/d) это вектор чья длина равняется единице, этот вектор есть (косинус(угол вектора к оси икс),косинус(к игрек), косинус(к зед))

векторное произведение.
Function Cross(x1#,y1#,z1#,x2#,y2#,z2#)

vecar(0,0)=y1*z2-y2*z1 ; икс
vecar(1,0)=z1*x2-z2*x1; игрек
vecar(2,0)=x1*y2-x2*y1;зед

End Function

А это скалярное
косинус( угол между векторами)=(x1*x2+y1*y2+z1*z2)/(l1*l2)

Уравнение плоскости в пространстве: ax+by+cz+d=0
вектор(a,b,c) перпендикулярен к этой плоскости, це нормаль. d смещение от оси координат.

tormoz 16.08.2011 01:32

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

;MsgDebug(str())


;******************************************
Declare RGBA(rl.l,g.l,b.l,l.l)
Structure v
  x.f
  y.f
  z.f
EndStructure

Structure pas
    mem.l[4]
    surf.l
    ver.l
EndStructure

Structure Sf
    surf.l
    entity.l
    ver.l
EndStructure

Structure act
    mem.l[4]
    surf.l
    ver.l
    x.f                    ;position
    y.f
    z.f
   
    xr.f                  ;rotate position entity
    yr.f
    ;zr.f
   
    xm.f                ;move entity
    ym.f
    zm.f
   
    xmd.f            ;delta move
    ymd.f
    zmd.f
   
    xt.f                ;turn entity
    yt.f
   
    xtd.f              ;delta turn
    ytd.f
 
    xd.f                ;speed translate
    yd.f
    zd.f
   
    xda.f            ;delta speedT
    yda.f
    zda.f
   
    r.f                  ;color
    g.f
    b.f
   
    rd.f              ;delta color
    gd.f
    bd.f
   
    rot.f              ;rotate texture
    al.f                ;alpha
    sc.f                ;size
    osc.f                ;size obraz
    fsqr.l            ;flag sqr
 
    rotd.f            ;delta rotate
    ald.f              ;delta alpha
    scd.f            ;delta scale
    liv.f              ;lives
    bild.l
EndStructure



ProcedureDLL AttachProcess(Hinstance)

Global  camera.l,vec
Global  surfPart
Global a.act
Global p.pas
Global  countP,countA
NewList a.act()
NewList p.pas()
NewList s.Sf()
Dim d.f(3,3)
EndProcedure

;*******************************************************************

ProcedureDLL CreateBank_tm(surf.l,count,cam)



f.l= PeekL(surf+28)
camera=cam
For ver.l=0 To count-1 Step 4
AddElement(p())
;MsgDebug(Str(ver))
p()\ver=ver
For i=0 To 3
p()\mem[i]=f.l+((ver+i)*64)
p()\surf=surf.l
PokeL(p()\mem[i]+24,RGBA(0,255,255,255))
Next

Next
AddElement(s())
s()\surf=surf
s()\entity=mesh
s()\ver=count-1
;MsgDebug(Str(s()\ver))
EndProcedure
;=====================================
ProcedureDLL AddBank_tm(surf.l,count)

f.l= PeekL(surf+28)
ForEach s()
 If  s()\surf=surf
    vera.l=s()\ver
  ; MsgDebug(Str(vera))
    s()\ver=s()\ver+count*4
   
EndIf
Next
;------------------------
For ver.l=vera+1 To vera+count*4 Step 4
AddElement(p())
p()\surf=surf.l

p()\ver=ver
For i=0 To 3
p()\mem[i]=f.l+((ver+i)*64)
PokeL(p()\mem[i]+24,RGBA(0,255,255,255))
Next

Next
;--------------------------

ForEach a()
  If  a()\surf=surf
    ;MsgDebug(Str(a()\ver))
    For i=0 To 3
        a()\mem[i]=f.l+((a()\ver+i)*64)
    Next
 EndIf
Next
;----------------------------
ForEach p()
  If  p()\surf=surf
    For i=0 To 3
        p()\mem[i]=f.l+((p()\ver+i)*64)
        PokeL(p()\mem[i]+24,RGBA(0,255,255,255))
    Next
 EndIf
Next
;-------------------
;

EndProcedure

;===============================
ProcedureDLL DeleteBank_tm(surf.l)
 ForEach a()
  If  a()\surf=surf
    DeleteElement(a())
  EndIf
 Next
ForEach p()
  If  p()\surf=surf
      DeleteElement(p())
  EndIf
 Next
 ForEach s()
  If  s()\surf=surf
      DeleteElement(s())
  EndIf
Next
EndProcedure
;================================
ProcedureDLL AddParticle_tm(surf.l,x.f, y.f, z.f, xr.f,yr.f,xm.f,ym.f,zm.f, xmd.f,ymd.f,zmd.f, xt.f,yt.f, xtd.f,ytd.f, xd.f, yd.f, zd.f,xda.f, yda.f, zda.f,r.f,g.f,b.f,rd.f,gd.f,bd.f, rot.f,rotd.f, al.f, ald.f, sc.f, scd.f,fsqr.l, liv.f,bild.l)
yspeh=0
e=LastElement(p())
ee:
If e<>0

      If  p()\surf<>surf
          e=PreviousElement(p())
          Goto ee
      EndIf

;----------------------------
yspeh=1
AddElement(a())
a()\ver=p()\ver
For i=0 To 3
a()\mem[i]=p()\mem[i]
PokeL(p()\mem[i]+24,RGBA(0,255,255,255))
Next


a()\surf=p()\surf

a()\x=x
a()\y=y
a()\z=z

a()\xr=xr*0.017453
a()\yr=yr*0.017453



a()\xm=xm
a()\ym=ym
a()\zm=zm

a()\xmd=xmd
a()\ymd=ymd
a()\zmd=zmd

a()\xt=xt
a()\yt=yt

a()\ xtd=xtd
a()\ ytd=ytd

a()\xd=xd
a()\yd=yd
a()\zd=zd

a()\xda=xda
a()\yda=yda
a()\zda=zda

a()\r=r
a()\g=g
a()\b=b

a()\rd=rd
a()\gd=gd
a()\bd=bd

 a()\rot=(rot-45)*0.017453

a()\al=al
a()\sc=sc
a()\osc=sc
a()\ rotd=rotd*0.017453

 a()\ald=ald
a()\scd=scd
a()\fsqr=fsqr.l

 a()\liv=liv
 a()\bild=bild
;=============================
PokeF (a()\mem[0],a()\x-1)
PokeF (a()\mem[0]+4,a()\y+1)
PokeF (a()\mem[0]+8,a()\z)

PokeF (a()\mem[1],a()\x+1)
PokeF (a()\mem[1]+4,a()\y+1)
PokeF (a()\mem[1]+8,a()\z)

PokeF (a()\mem[2],a()\x+1)
PokeF (a()\mem[2]+4,a()\y-1)
PokeF (a()\mem[2]+8,a()\z)

PokeF (a()\mem[3],a()\x-1)
PokeF (a()\mem[3]+4,a()\y-1)
PokeF (a()\mem[3]+8,a()\z)

DeleteElement(p())

EndIf
ProcedureReturn yspeh
EndProcedure
;================================
ProcedureDLL UpdateParticle_tm()
 countA=0
 ;============================
 camX.f=PeekF(camera+16*4)
  camY.f=PeekF(camera+17*4)
 camZ.f=PeekF(camera+18*4)
ForEach a()
;countA=countA+1
;-------------------color===========
a()\r=a()\r+a()\rd
a()\g=a()\g+a()\gd
a()\b=a()\b+a()\bd
If a()\r>255
  a()\r=255
EndIf
If a()\g>255
  a()\g=255
EndIf
If a()\b>255
  a()\b=255
EndIf

If a()\r<0
  a()\r=0
EndIf
If a()\g<0
  a()\g=0
EndIf
If a()\b<0
  a()\b=0
EndIf
;===========alpha==========
a()\al=a()\al+a()\ald

If a()\al>255
  a()\al=255
EndIf
 If a()\al<0
  a()\al=0
EndIf
;==============turn===========
a()\ rot=a()\ rot+a()\ rotd  ;texture


a()\xt=a()\xt+a()\xtd
a()\yt=a()\yt+a()\ytd


a()\xr=a()\xr+a()\xt
a()\yr=a()\yr+a()\yt

;===============move===========
If  a()\xm>0   
  a()\xm=a()\xm*a()\xmd
 
 EndIf
If  a()\ym>0 
    a()\ym=a()\ym*a()\ymd
EndIf
If  a()\zm>0 
    a()\zm=a()\zm*a()\zmd
 EndIf
sinXm.f=Sin(a()\xr)
sinYm.f=Sin(a()\yr)
cosXm.f=Cos(a()\xr)
cosYm.f=Cos(a()\yr)

a()\x=a()\x +( a()\xm*cosYm+a()\ym*-sinXm*sinYm+a()\zm*-sinYm*cosXm)
a()\y=a()\y+( a()\ym*cosXm+a()\zm*-sinXm )
a()\z=a()\z+( a()\xm*sinYm+a()\ym*sinXm*cosYm+a()\zm*cosYm*cosXm)
;a()\x=a()\x +( a()\xm*Cos(a()\yr)+a()\ym*-Sin(a()\xr)*Sin(a()\yr)+a()\zm*-Sin(a()\yr)*Cos(a()\xr) )
;a()\y=a()\y+( a()\ym*Cos(a()\xr)+a()\zm*-Sin(a()\xr)  )
;a()\z=a()\z+( a()\xm*Sin(a()\yr)+a()\ym*Sin(a()\xr)*Cos(a()\yr)+a()\zm*Cos(a()\yr)*Cos(a()\xr) )

;===========translate==========
a()\xd=a()\xd+a()\xda
a()\yd=a()\yd+a()\yda
a()\zd=a()\zd+a()\zda

a()\x=a()\x +a()\xd
a()\y=a()\y+a()\yd
a()\z=a()\z+a()\zd
;========scale==========
 If a()\fsqr
  a()\sc=a()\sc* (a()\scd*0.5* Sqr(a()\osc/a()\sc)+a()\scd*0.5)
 Else
    a()\sc=a()\sc*a()\scd
 EndIf


 If a()\bild=0
 

  xn.f=a()\x-camX
  yn.f=a()\y-camY
  zn.f=a()\z-camZ
  Else
    xn.f=1
    yn.f=0
    zn.f=100
  EndIf 
 ;--------------------normalisate--------
l.f = Sqr(xn*xn + yn*yn + zn*zn)

vecy.f = yn.f/l
 
l.f = Sqr(xn*xn + zn*zn)
zna.f=zn.f/l
;------------------angle normals----------
anX.f=ACos(vecy )-1.57
anY.f=ACos(zna)*-(xn/Abs(xn))
 ;-----------------------------
 sina.f=a()\sc*Sin(a()\ rot)*0.7
 cosa.f=a()\sc*Cos(a()\ rot)*0.7
 
 sinX.f=Sin(anX)
 sinY.f=Sin(anY)
 cosx.f=Cos(anX)
 cosY.f=Cos(anY)


d(0,0)=-sina*cosY+cosa*(-sinX*sinY)+a()\x
d(0,1)=cosa*cosx+a()\y
d(0,2)=-sina*sinY+cosa*sinX*cosx+a()\z


d(1,0)=cosa*cosY+sina*(-sinX*sinY)+a()\x
d(1,1)=sina*cosx+a()\y
d(1,2)=cosa*sinY+sina*sinX*cosY+a()\z


d(2,0)=sina*cosY-cosa*(-sinX*sinY)+a()\x
d(2,1)=-cosa*cosx+a()\y
d(2,2)=sina*sinY-cosa*sinX*Cos(anY)+a()\z

d(3,0)=-cosa*cosY-sina*(-sinX*sinY)+a()\x
d(3,1)=-sina*cosx+a()\y
d(3,2)=-cosa*sinY-sina*sinX*cosY+a()\z

;----------------------------------
For i=0 To 3
    PokeF (a()\mem[i],d(i,0))
    PokeF (a()\mem[i]+4,d(i,1))
    PokeF (a()\mem[i]+8,d(i,2))
    PokeL(a()\mem[i]+24,RGBA(a()\al,a()\r,a()\g,a()\b))
Next


;===============live=============
a()\liv=a()\liv-1
If a()\liv<0 Or a()\al<0.01
AddElement(p())
p()\surf=a()\surf
p()\ver=a()\ver
For i=0 To 3
p()\mem[i]=a()\mem[i]
c.f=Random(10)*i
PokeF (p()\mem[i],a()\x+c)
PokeF (p()\mem[i]+4,a()\y+c)
PokeF (p()\mem[i]+8,a()\z-c) 

  PokeL(p()\mem[i]+24,RGBA(0,255,255,255))
Next
;=============================
DeleteElement(a())

EndIf

Next

ForEach s()

PokeL(s()\surf+64,0)

Next
ProcedureReturn CountList(a())
EndProcedure
;================================
Procedure RGBA(rl.l,gl.l,bl.l,l.l)
  MOV eax,rl
 SHL eax,24
 MOV ebx,gl
 SHL ebx,16
 MOV edx,bl
 SHL edx,8
 OR eax,ebx
 OR eax,edx
 OR eax,l
  ProcedureReturn
EndProcedure
;==============================



; IDE Options = PureBasic 4.10 Beta 2 (Windows - x86)
; ExecutableFormat = Shared Dll
; CursorPosition = 81
; FirstLine = 67
; Folding = --
; EnableAsm
; Executable = particle_amt.dll
; ExecutableFormat=Shared Dll
; EnableAsm
;
; EOF


L.D.M.T. 16.08.2011 19:02

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

dsd 16.08.2011 19:14

Ответ: Организация системы частиц
 
А переписать пошагово не вариант?


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

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