EditorParticleEffect.as 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497
  1. // Urho3D material editor
  2. Window@ particleEffectWindow;
  3. ParticleEffect@ editParticleEffect;
  4. XMLFile@ oldParticleEffectState;
  5. bool inParticleEffectRefresh = false;
  6. View3D@ particleEffectPreview;
  7. Scene@ particlePreviewScene;
  8. Node@ particleEffectPreviewNode;
  9. Node@ particlePreviewCameraNode;
  10. Node@ particlePreviewLightNode;
  11. Light@ particlePreviewLight;
  12. ParticleEmitter@ particleEffectEmitter;
  13. float particleResetTimer;
  14. void CreateParticleEffectEditor()
  15. {
  16. if (particleEffectWindow !is null)
  17. return;
  18. particleEffectWindow = LoadEditorUI("UI/EditorParticleEffectWindow.xml");
  19. ui.root.AddChild(particleEffectWindow);
  20. particleEffectWindow.opacity = uiMaxOpacity;
  21. InitParticleEffectPreview();
  22. InitParticleEffectBasicAttributes();
  23. RefreshParticleEffectEditor();
  24. int height = Min(ui.root.height - 60, 500);
  25. particleEffectWindow.SetSize(300, height);
  26. CenterDialog(particleEffectWindow);
  27. HideParticleEffectEditor();
  28. SubscribeToEvent(particleEffectWindow.GetChild("NewButton", true), "Released", "NewParticleEffect");
  29. SubscribeToEvent(particleEffectWindow.GetChild("RevertButton", true), "Released", "RevertParticleEffect");
  30. SubscribeToEvent(particleEffectWindow.GetChild("SaveButton", true), "Released", "SaveParticleEffect");
  31. SubscribeToEvent(particleEffectWindow.GetChild("SaveAsButton", true), "Released", "SaveParticleEffectAs");
  32. SubscribeToEvent(particleEffectWindow.GetChild("CloseButton", true), "Released", "HideParticleEffectEditor");
  33. SubscribeToEvent(particleEffectWindow.GetChild("NewColorFrame", true), "Released", "EditParticleEffectColorFrameNew");
  34. SubscribeToEvent(particleEffectWindow.GetChild("RemoveColorFrame", true), "Released", "EditParticleEffectColorFrameRemove");
  35. SubscribeToEvent(particleEffectWindow.GetChild("ColorFrameSort", true), "Released", "EditParticleEffectColorFrameSort");
  36. SubscribeToEvent(particleEffectWindow.GetChild("NewTextureFrame", true), "Released", "EditParticleEffectTextureFrameNew");
  37. SubscribeToEvent(particleEffectWindow.GetChild("RemoveTextureFrame", true), "Released", "EditParticleEffectTextureFrameRemove");
  38. SubscribeToEvent(particleEffectWindow.GetChild("TextureFrameSort", true), "Released", "EditParticleEffectTextureFrameSort");
  39. SubscribeToEvent(particleEffectWindow.GetChild("ConstantForceX", true), "TextChanged", "EditParticleEffectConstantForce");
  40. SubscribeToEvent(particleEffectWindow.GetChild("ConstantForceY", true), "TextChanged", "EditParticleEffectConstantForce");
  41. SubscribeToEvent(particleEffectWindow.GetChild("ConstantForceZ", true), "TextChanged", "EditParticleEffectConstantForce");
  42. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMinX", true), "TextChanged", "EditParticleEffectDirection");
  43. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMinY", true), "TextChanged", "EditParticleEffectDirection");
  44. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMinZ", true), "TextChanged", "EditParticleEffectDirection");
  45. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMaxX", true), "TextChanged", "EditParticleEffectDirection");
  46. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMaxY", true), "TextChanged", "EditParticleEffectDirection");
  47. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMaxZ", true), "TextChanged", "EditParticleEffectDirection");
  48. SubscribeToEvent(particleEffectWindow.GetChild("DampingForce", true), "TextChanged", "EditParticleEffectDampingForce");
  49. SubscribeToEvent(particleEffectWindow.GetChild("ActiveTime", true), "TextChanged", "EditParticleEffectActiveTime");
  50. SubscribeToEvent(particleEffectWindow.GetChild("InactiveTime", true), "TextChanged", "EditParticleEffectInactiveTime");
  51. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMinX", true), "TextChanged", "EditParticleEffectParticleSize");
  52. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMinY", true), "TextChanged", "EditParticleEffectParticleSize");
  53. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMaxX", true), "TextChanged", "EditParticleEffectParticleSize");
  54. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMaxY", true), "TextChanged", "EditParticleEffectParticleSize");
  55. SubscribeToEvent(particleEffectWindow.GetChild("TimeToLiveMin", true), "TextChanged", "EditParticleEffectTimeToLive");
  56. SubscribeToEvent(particleEffectWindow.GetChild("TimeToLiveMax", true), "TextChanged", "EditParticleEffectTimeToLive");
  57. SubscribeToEvent(particleEffectWindow.GetChild("VelocityMin", true), "TextChanged", "EditParticleEffectVelocity");
  58. SubscribeToEvent(particleEffectWindow.GetChild("VelocityMax", true), "TextChanged", "EditParticleEffectVelocity");
  59. SubscribeToEvent(particleEffectWindow.GetChild("RotationMin", true), "TextChanged", "EditParticleEffectRotation");
  60. SubscribeToEvent(particleEffectWindow.GetChild("RotationMax", true), "TextChanged", "EditParticleEffectRotation");
  61. SubscribeToEvent(particleEffectWindow.GetChild("RotationSpeedMin", true), "TextChanged", "EditParticleEffectRotationSpeed");
  62. SubscribeToEvent(particleEffectWindow.GetChild("RotationSpeedMax", true), "TextChanged", "EditParticleEffectRotationSpeed");
  63. SubscribeToEvent(particleEffectWindow.GetChild("SizeAdd", true), "TextChanged", "EditParticleEffectSizeAdd");
  64. SubscribeToEvent(particleEffectWindow.GetChild("SizeMultiply", true), "TextChanged", "EditParticleEffectSizeMultiply");
  65. SubscribeToEvent(particleEffectWindow.GetChild("AnimationLodBias", true), "TextChanged", "EditParticleEffectAnimationLodBias");
  66. SubscribeToEvent(particleEffectWindow.GetChild("NumParticles", true), "TextChanged", "EditParticleEffectNumParticles");
  67. SubscribeToEvent(particleEffectWindow.GetChild("EmitterSizeX", true), "TextChanged", "EditParticleEffectEmitterSize");
  68. SubscribeToEvent(particleEffectWindow.GetChild("EmitterSizeY", true), "TextChanged", "EditParticleEffectEmitterSize");
  69. SubscribeToEvent(particleEffectWindow.GetChild("EmitterSizeZ", true), "TextChanged", "EditParticleEffectEmitterSize");
  70. SubscribeToEvent(particleEffectWindow.GetChild("EmissionRateMin", true), "TextChanged", "EditParticleEffectEmissionRate");
  71. SubscribeToEvent(particleEffectWindow.GetChild("EmissionRateMax", true), "TextChanged", "EditParticleEffectEmissionRate");
  72. SubscribeToEvent(particleEffectWindow.GetChild("ConstantForceX", true), "TextFinished", "EditParticleEffectConstantForce");
  73. SubscribeToEvent(particleEffectWindow.GetChild("ConstantForceY", true), "TextFinished", "EditParticleEffectConstantForce");
  74. SubscribeToEvent(particleEffectWindow.GetChild("ConstantForceZ", true), "TextFinished", "EditParticleEffectConstantForce");
  75. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMinX", true), "TextFinished", "EditParticleEffectDirection");
  76. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMinY", true), "TextFinished", "EditParticleEffectDirection");
  77. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMinZ", true), "TextFinished", "EditParticleEffectDirection");
  78. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMaxX", true), "TextFinished", "EditParticleEffectDirection");
  79. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMaxY", true), "TextFinished", "EditParticleEffectDirection");
  80. SubscribeToEvent(particleEffectWindow.GetChild("DirectionMaxZ", true), "TextFinished", "EditParticleEffectDirection");
  81. SubscribeToEvent(particleEffectWindow.GetChild("DampingForce", true), "TextFinished", "EditParticleEffectDampingForce");
  82. SubscribeToEvent(particleEffectWindow.GetChild("ActiveTime", true), "TextFinished", "EditParticleEffectActiveTime");
  83. SubscribeToEvent(particleEffectWindow.GetChild("InactiveTime", true), "TextFinished", "EditParticleEffectInactiveTime");
  84. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMinX", true), "TextFinished", "EditParticleEffectParticleSize");
  85. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMinY", true), "TextFinished", "EditParticleEffectParticleSize");
  86. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMaxX", true), "TextFinished", "EditParticleEffectParticleSize");
  87. SubscribeToEvent(particleEffectWindow.GetChild("ParticleSizeMaxY", true), "TextFinished", "EditParticleEffectParticleSize");
  88. SubscribeToEvent(particleEffectWindow.GetChild("TimeToLiveMin", true), "TextFinished", "EditParticleEffectTimeToLive");
  89. SubscribeToEvent(particleEffectWindow.GetChild("TimeToLiveMax", true), "TextFinished", "EditParticleEffectTimeToLive");
  90. SubscribeToEvent(particleEffectWindow.GetChild("VelocityMin", true), "TextFinished", "EditParticleEffectVelocity");
  91. SubscribeToEvent(particleEffectWindow.GetChild("VelocityMax", true), "TextFinished", "EditParticleEffectVelocity");
  92. SubscribeToEvent(particleEffectWindow.GetChild("RotationMin", true), "TextFinished", "EditParticleEffectRotation");
  93. SubscribeToEvent(particleEffectWindow.GetChild("RotationMax", true), "TextFinished", "EditParticleEffectRotation");
  94. SubscribeToEvent(particleEffectWindow.GetChild("RotationSpeedMin", true), "TextFinished", "EditParticleEffectRotationSpeed");
  95. SubscribeToEvent(particleEffectWindow.GetChild("RotationSpeedMax", true), "TextFinished", "EditParticleEffectRotationSpeed");
  96. SubscribeToEvent(particleEffectWindow.GetChild("SizeAdd", true), "TextFinished", "EditParticleEffectSizeAdd");
  97. SubscribeToEvent(particleEffectWindow.GetChild("SizeMultiply", true), "TextFinished", "EditParticleEffectSizeMultiply");
  98. SubscribeToEvent(particleEffectWindow.GetChild("AnimationLodBias", true), "TextFinished", "EditParticleEffectAnimationLodBias");
  99. SubscribeToEvent(particleEffectWindow.GetChild("NumParticles", true), "TextFinished", "EditParticleEffectNumParticles");
  100. SubscribeToEvent(particleEffectWindow.GetChild("EmitterSizeX", true), "TextFinished", "EditParticleEffectEmitterSize");
  101. SubscribeToEvent(particleEffectWindow.GetChild("EmitterSizeY", true), "TextFinished", "EditParticleEffectEmitterSize");
  102. SubscribeToEvent(particleEffectWindow.GetChild("EmitterSizeZ", true), "TextFinished", "EditParticleEffectEmitterSize");
  103. SubscribeToEvent(particleEffectWindow.GetChild("EmissionRateMin", true), "TextFinished", "EditParticleEffectEmissionRate");
  104. SubscribeToEvent(particleEffectWindow.GetChild("EmissionRateMax", true), "TextFinished", "EditParticleEffectEmissionRate");
  105. SubscribeToEvent(particleEffectWindow.GetChild("EmitterShape", true), "ItemSelected", "EditParticleEffectEmitterShape");
  106. SubscribeToEvent(particleEffectWindow.GetChild("Scaled", true), "Toggled", "EditParticleEffectScaled");
  107. SubscribeToEvent(particleEffectWindow.GetChild("Sorted", true), "Toggled", "EditParticleEffectSorted");
  108. SubscribeToEvent(particleEffectWindow.GetChild("Relative", true), "Toggled", "EditParticleEffectRelative");
  109. }
  110. void EditParticleEffectColorFrameNew(StringHash eventType, VariantMap& eventData)
  111. {
  112. if (inParticleEffectRefresh)
  113. return;
  114. if (editParticleEffect is null)
  115. return;
  116. BeginParticleEffectEdit();
  117. uint num = editParticleEffect.numColorFrames;
  118. editParticleEffect.numColorFrames = num + 1;
  119. RefreshParticleEffectColorFrames();
  120. EndParticleEffectEdit();
  121. }
  122. void EditParticleEffectTextureFrameNew(StringHash eventType, VariantMap& eventData)
  123. {
  124. if (inParticleEffectRefresh)
  125. return;
  126. if (editParticleEffect is null)
  127. return;
  128. BeginParticleEffectEdit();
  129. uint num = editParticleEffect.numTextureFrames;
  130. editParticleEffect.numTextureFrames = num + 1;
  131. RefreshParticleEffectTextureFrames();
  132. EndParticleEffectEdit();
  133. }
  134. void EditParticleEffectColorFrameRemove(StringHash eventType, VariantMap& eventData)
  135. {
  136. if (inParticleEffectRefresh)
  137. return;
  138. if (editParticleEffect is null)
  139. return;
  140. ListView@ lv = particleEffectWindow.GetChild("ColorFrameListView", true);
  141. if (lv !is null && lv.selection != M_MAX_UNSIGNED )
  142. {
  143. BeginParticleEffectEdit();
  144. editParticleEffect.RemoveColorFrame(lv.selection);
  145. RefreshParticleEffectColorFrames();
  146. EndParticleEffectEdit();
  147. }
  148. }
  149. void EditParticleEffectTextureFrameRemove(StringHash eventType, VariantMap& eventData)
  150. {
  151. if (inParticleEffectRefresh)
  152. return;
  153. if (editParticleEffect is null)
  154. return;
  155. ListView@ lv = particleEffectWindow.GetChild("TextureFrameListView", true);
  156. if (lv !is null && lv.selection != M_MAX_UNSIGNED )
  157. {
  158. BeginParticleEffectEdit();
  159. editParticleEffect.RemoveTextureFrame(lv.selection);
  160. RefreshParticleEffectTextureFrames();
  161. EndParticleEffectEdit();
  162. }
  163. }
  164. void EditParticleEffectColorFrameSort(StringHash eventType, VariantMap& eventData)
  165. {
  166. RefreshParticleEffectColorFrames();
  167. }
  168. void EditParticleEffectTextureFrameSort(StringHash eventType, VariantMap& eventData)
  169. {
  170. RefreshParticleEffectTextureFrames();
  171. }
  172. void InitParticleEffectBasicAttributes()
  173. {
  174. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ConstantForceX", true)));
  175. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ConstantForceY", true)));
  176. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ConstantForceZ", true)));
  177. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DirectionMinX", true)));
  178. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DirectionMinY", true)));
  179. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DirectionMinZ", true)));
  180. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DirectionMaxX", true)));
  181. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DirectionMaxY", true)));
  182. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DirectionMaxZ", true)));
  183. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("DampingForce", true)));
  184. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ActiveTime", true)));
  185. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("InactiveTime", true)));
  186. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMinX", true)));
  187. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMinY", true)));
  188. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMaxX", true)));
  189. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMaxY", true)));
  190. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("TimeToLiveMin", true)));
  191. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("TimeToLiveMax", true)));
  192. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("VelocityMin", true)));
  193. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("VelocityMax", true)));
  194. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("RotationMin", true)));
  195. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("RotationMax", true)));
  196. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("RotationSpeedMin", true)));
  197. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("RotationSpeedMax", true)));
  198. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("SizeAdd", true)));
  199. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("SizeMultiply", true)));
  200. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("AnimationLodBias", true)));
  201. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("NumParticles", true)));
  202. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("EmitterSizeX", true)));
  203. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("EmitterSizeY", true)));
  204. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("EmitterSizeZ", true)));
  205. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("EmissionRateMin", true)));
  206. CreateDragSlider(cast<LineEdit>(particleEffectWindow.GetChild("EmissionRateMax", true)));
  207. }
  208. void EditParticleEffectConstantForce(StringHash eventType, VariantMap& eventData)
  209. {
  210. if (inParticleEffectRefresh)
  211. return;
  212. if (editParticleEffect is null)
  213. return;
  214. BeginParticleEffectEdit();
  215. LineEdit@ element = eventData["Element"].GetPtr();
  216. Vector3 v = editParticleEffect.constantForce;
  217. if (element.name == "ConstantForceX")
  218. editParticleEffect.constantForce = Vector3(element.text.ToFloat(), v.y, v.z);
  219. if (element.name == "ConstantForceY")
  220. editParticleEffect.constantForce = Vector3(v.x, element.text.ToFloat(), v.z);
  221. if (element.name == "ConstantForceZ")
  222. editParticleEffect.constantForce = Vector3(v.x, v.y, element.text.ToFloat());
  223. EndParticleEffectEdit();
  224. }
  225. void EditParticleEffectDirection(StringHash eventType, VariantMap& eventData)
  226. {
  227. if (inParticleEffectRefresh)
  228. return;
  229. if (editParticleEffect is null)
  230. return;
  231. BeginParticleEffectEdit();
  232. LineEdit@ element = eventData["Element"].GetPtr();
  233. Vector3 vMin = editParticleEffect.minDirection;
  234. Vector3 vMax = editParticleEffect.maxDirection;
  235. if (element.name == "DirectionMinX")
  236. editParticleEffect.minDirection = Vector3(element.text.ToFloat(), vMin.y, vMin.z);
  237. if (element.name == "DirectionMinY")
  238. editParticleEffect.minDirection = Vector3(vMin.x, element.text.ToFloat(), vMin.z);
  239. if (element.name == "DirectionMinZ")
  240. editParticleEffect.minDirection = Vector3(vMin.x, vMin.y, element.text.ToFloat());
  241. if (element.name == "DirectionMaxX")
  242. editParticleEffect.maxDirection = Vector3(element.text.ToFloat(), vMax.y, vMax.z);
  243. if (element.name == "DirectionMaxY")
  244. editParticleEffect.maxDirection = Vector3(vMax.x, element.text.ToFloat(), vMax.z);
  245. if (element.name == "DirectionMaxZ")
  246. editParticleEffect.maxDirection = Vector3(vMax.x, vMax.y, element.text.ToFloat());
  247. EndParticleEffectEdit();
  248. }
  249. void EditParticleEffectDampingForce(StringHash eventType, VariantMap& eventData)
  250. {
  251. if (inParticleEffectRefresh)
  252. return;
  253. if (editParticleEffect is null)
  254. return;
  255. BeginParticleEffectEdit();
  256. LineEdit@ element = eventData["Element"].GetPtr();
  257. editParticleEffect.dampingForce = element.text.ToFloat();
  258. EndParticleEffectEdit();
  259. }
  260. void EditParticleEffectActiveTime(StringHash eventType, VariantMap& eventData)
  261. {
  262. if (inParticleEffectRefresh)
  263. return;
  264. if (editParticleEffect is null)
  265. return;
  266. if (particleEffectEmitter is null)
  267. return;
  268. BeginParticleEffectEdit();
  269. LineEdit@ element = eventData["Element"].GetPtr();
  270. editParticleEffect.activeTime = element.text.ToFloat();
  271. particleEffectEmitter.Reset();
  272. EndParticleEffectEdit();
  273. }
  274. void EditParticleEffectInactiveTime(StringHash eventType, VariantMap& eventData)
  275. {
  276. if (inParticleEffectRefresh)
  277. return;
  278. if (editParticleEffect is null)
  279. return;
  280. if (particleEffectEmitter is null)
  281. return;
  282. BeginParticleEffectEdit();
  283. LineEdit@ element = eventData["Element"].GetPtr();
  284. editParticleEffect.inactiveTime = element.text.ToFloat();
  285. particleEffectEmitter.Reset();
  286. EndParticleEffectEdit();
  287. }
  288. void EditParticleEffectParticleSize(StringHash eventType, VariantMap& eventData)
  289. {
  290. if (inParticleEffectRefresh)
  291. return;
  292. if (editParticleEffect is null)
  293. return;
  294. BeginParticleEffectEdit();
  295. LineEdit@ element = eventData["Element"].GetPtr();
  296. Vector2 vMin = editParticleEffect.minParticleSize;
  297. Vector2 vMax = editParticleEffect.maxParticleSize;
  298. if (element.name == "ParticleSizeMinX")
  299. editParticleEffect.minParticleSize = Vector2(element.text.ToFloat(), vMin.y);
  300. if (element.name == "ParticleSizeMinY")
  301. editParticleEffect.minParticleSize = Vector2(vMin.x, element.text.ToFloat());
  302. if (element.name == "ParticleSizeMaxX")
  303. editParticleEffect.maxParticleSize = Vector2(element.text.ToFloat(), vMax.y);
  304. if (element.name == "ParticleSizeMaxY")
  305. editParticleEffect.maxParticleSize = Vector2(vMax.x, element.text.ToFloat());
  306. EndParticleEffectEdit();
  307. }
  308. void EditParticleEffectTimeToLive(StringHash eventType, VariantMap& eventData)
  309. {
  310. if (inParticleEffectRefresh)
  311. return;
  312. if (editParticleEffect is null)
  313. return;
  314. BeginParticleEffectEdit();
  315. LineEdit@ element = eventData["Element"].GetPtr();
  316. float vMin = editParticleEffect.minTimeToLive;
  317. float vMax = editParticleEffect.maxTimeToLive;
  318. if (element.name == "TimeToLiveMin")
  319. editParticleEffect.minTimeToLive = element.text.ToFloat();
  320. if (element.name == "TimeToLiveMax")
  321. editParticleEffect.maxTimeToLive = element.text.ToFloat();
  322. EndParticleEffectEdit();
  323. }
  324. void EditParticleEffectVelocity(StringHash eventType, VariantMap& eventData)
  325. {
  326. if (inParticleEffectRefresh)
  327. return;
  328. if (editParticleEffect is null)
  329. return;
  330. BeginParticleEffectEdit();
  331. LineEdit@ element = eventData["Element"].GetPtr();
  332. float vMin = editParticleEffect.minVelocity;
  333. float vMax = editParticleEffect.maxVelocity;
  334. if (element.name == "VelocityMin")
  335. editParticleEffect.minVelocity = element.text.ToFloat();
  336. if (element.name == "VelocityMax")
  337. editParticleEffect.maxVelocity = element.text.ToFloat();
  338. EndParticleEffectEdit();
  339. }
  340. void EditParticleEffectRotation(StringHash eventType, VariantMap& eventData)
  341. {
  342. if (inParticleEffectRefresh)
  343. return;
  344. if (editParticleEffect is null)
  345. return;
  346. BeginParticleEffectEdit();
  347. LineEdit@ element = eventData["Element"].GetPtr();
  348. float vMin = editParticleEffect.minRotation;
  349. float vMax = editParticleEffect.maxRotation;
  350. if (element.name == "RotationMin")
  351. editParticleEffect.minRotation = element.text.ToFloat();
  352. if (element.name == "RotationMax")
  353. editParticleEffect.maxRotation = element.text.ToFloat();
  354. EndParticleEffectEdit();
  355. }
  356. void EditParticleEffectRotationSpeed(StringHash eventType, VariantMap& eventData)
  357. {
  358. if (inParticleEffectRefresh)
  359. return;
  360. if (editParticleEffect is null)
  361. return;
  362. BeginParticleEffectEdit();
  363. LineEdit@ element = eventData["Element"].GetPtr();
  364. float vMin = editParticleEffect.minRotationSpeed;
  365. float vMax = editParticleEffect.maxRotationSpeed;
  366. if (element.name == "RotationSpeedMin")
  367. editParticleEffect.minRotationSpeed = element.text.ToFloat();
  368. if (element.name == "RotationSpeedMax")
  369. editParticleEffect.maxRotationSpeed = element.text.ToFloat();
  370. EndParticleEffectEdit();
  371. }
  372. void EditParticleEffectSizeAdd(StringHash eventType, VariantMap& eventData)
  373. {
  374. if (inParticleEffectRefresh)
  375. return;
  376. if (editParticleEffect is null)
  377. return;
  378. BeginParticleEffectEdit();
  379. LineEdit@ element = eventData["Element"].GetPtr();
  380. editParticleEffect.sizeAdd = element.text.ToFloat();
  381. EndParticleEffectEdit();
  382. }
  383. void EditParticleEffectSizeMultiply(StringHash eventType, VariantMap& eventData)
  384. {
  385. if (inParticleEffectRefresh)
  386. return;
  387. if (editParticleEffect is null)
  388. return;
  389. BeginParticleEffectEdit();
  390. LineEdit@ element = eventData["Element"].GetPtr();
  391. editParticleEffect.sizeMul = element.text.ToFloat();
  392. EndParticleEffectEdit();
  393. }
  394. void EditParticleEffectAnimationLodBias(StringHash eventType, VariantMap& eventData)
  395. {
  396. if (inParticleEffectRefresh)
  397. return;
  398. if (editParticleEffect is null)
  399. return;
  400. BeginParticleEffectEdit();
  401. LineEdit@ element = eventData["Element"].GetPtr();
  402. editParticleEffect.animationLodBias = element.text.ToFloat();
  403. EndParticleEffectEdit();
  404. }
  405. void EditParticleEffectNumParticles(StringHash eventType, VariantMap& eventData)
  406. {
  407. if (inParticleEffectRefresh)
  408. return;
  409. if (editParticleEffect is null)
  410. return;
  411. if (particleEffectEmitter is null)
  412. return;
  413. BeginParticleEffectEdit();
  414. LineEdit@ element = eventData["Element"].GetPtr();
  415. editParticleEffect.numParticles = element.text.ToInt();
  416. particleEffectEmitter.ApplyEffect();
  417. EndParticleEffectEdit();
  418. }
  419. void EditParticleEffectEmitterSize(StringHash eventType, VariantMap& eventData)
  420. {
  421. if (inParticleEffectRefresh)
  422. return;
  423. if (editParticleEffect is null)
  424. return;
  425. BeginParticleEffectEdit();
  426. LineEdit@ element = eventData["Element"].GetPtr();
  427. Vector3 v = editParticleEffect.emitterSize;
  428. if (element.name == "EmitterSizeX")
  429. editParticleEffect.emitterSize = Vector3(element.text.ToFloat(), v.y, v.z);
  430. if (element.name == "EmitterSizeY")
  431. editParticleEffect.emitterSize = Vector3(v.x, element.text.ToFloat(), v.z);
  432. if (element.name == "EmitterSizeZ")
  433. editParticleEffect.emitterSize = Vector3(v.x, v.y, element.text.ToFloat());
  434. EndParticleEffectEdit();
  435. }
  436. void EditParticleEffectEmissionRate(StringHash eventType, VariantMap& eventData)
  437. {
  438. if (inParticleEffectRefresh)
  439. return;
  440. if (editParticleEffect is null)
  441. return;
  442. BeginParticleEffectEdit();
  443. LineEdit@ element = eventData["Element"].GetPtr();
  444. if (element.name == "EmissionRateMin")
  445. editParticleEffect.minEmissionRate = element.text.ToFloat();
  446. if (element.name == "EmissionRateMax")
  447. editParticleEffect.maxEmissionRate = element.text.ToFloat();
  448. EndParticleEffectEdit();
  449. }
  450. void EditParticleEffectEmitterShape(StringHash eventType, VariantMap& eventData)
  451. {
  452. if (inParticleEffectRefresh)
  453. return;
  454. if (editParticleEffect is null)
  455. return;
  456. BeginParticleEffectEdit();
  457. DropDownList@ element = eventData["Element"].GetPtr();
  458. switch (element.selection)
  459. {
  460. case 0:
  461. editParticleEffect.emitterType = EMITTER_BOX;
  462. break;
  463. case 1:
  464. editParticleEffect.emitterType = EMITTER_SPHERE;
  465. break;
  466. }
  467. EndParticleEffectEdit();
  468. }
  469. void EditParticleEffectMaterial(StringHash eventType, VariantMap& eventData)
  470. {
  471. if (inParticleEffectRefresh)
  472. return;
  473. if (editParticleEffect is null)
  474. return;
  475. if (particleEffectEmitter is null)
  476. return;
  477. LineEdit@ element = eventData["Element"].GetPtr();
  478. Material@ res = cache.GetResource("Material", element.text);
  479. if (res !is null)
  480. {
  481. BeginParticleEffectEdit();
  482. editParticleEffect.material = res;
  483. particleEffectEmitter.ApplyEffect();
  484. EndParticleEffectEdit();
  485. }
  486. }
  487. void PickEditParticleEffectMaterial(StringHash eventType, VariantMap& eventData)
  488. {
  489. @resourcePicker = GetResourcePicker(StringHash("Material"));
  490. if (resourcePicker is null)
  491. return;
  492. String lastPath = resourcePicker.lastPath;
  493. if (lastPath.empty)
  494. lastPath = sceneResourcePath;
  495. CreateFileSelector("Pick " + resourcePicker.typeName, "OK", "Cancel", lastPath, resourcePicker.filters, resourcePicker.lastFilter);
  496. SubscribeToEvent(uiFileSelector, "FileSelected", "PickEditParticleEffectMaterialDone");
  497. }
  498. void PickEditParticleEffectMaterialDone(StringHash eventType, VariantMap& eventData)
  499. {
  500. StoreResourcePickerPath();
  501. CloseFileSelector();
  502. if (!eventData["OK"].GetBool())
  503. {
  504. @resourcePicker = null;
  505. return;
  506. }
  507. String resourceName = eventData["FileName"].GetString();
  508. Resource@ res = GetPickedResource(resourceName);
  509. if (res !is null && editParticleEffect !is null && particleEffectEmitter !is null)
  510. {
  511. editParticleEffect.material = res;
  512. particleEffectEmitter.ApplyEffect();
  513. RefreshParticleEffectMaterial();
  514. }
  515. @resourcePicker = null;
  516. }
  517. void EditParticleEffectScaled(StringHash eventType, VariantMap& eventData)
  518. {
  519. if (inParticleEffectRefresh)
  520. return;
  521. if (editParticleEffect is null)
  522. return;
  523. if (particleEffectEmitter is null)
  524. return;
  525. BeginParticleEffectEdit();
  526. CheckBox@ element = eventData["Element"].GetPtr();
  527. editParticleEffect.scaled = element.checked;
  528. particleEffectEmitter.ApplyEffect();
  529. EndParticleEffectEdit();
  530. }
  531. void EditParticleEffectSorted(StringHash eventType, VariantMap& eventData)
  532. {
  533. if (inParticleEffectRefresh)
  534. return;
  535. if (editParticleEffect is null)
  536. return;
  537. if (particleEffectEmitter is null)
  538. return;
  539. BeginParticleEffectEdit();
  540. CheckBox@ element = eventData["Element"].GetPtr();
  541. editParticleEffect.sorted = element.checked;
  542. particleEffectEmitter.ApplyEffect();
  543. EndParticleEffectEdit();
  544. }
  545. void EditParticleEffectRelative(StringHash eventType, VariantMap& eventData)
  546. {
  547. if (inParticleEffectRefresh)
  548. return;
  549. if (editParticleEffect is null)
  550. return;
  551. if (particleEffectEmitter is null)
  552. return;
  553. BeginParticleEffectEdit();
  554. CheckBox@ element = eventData["Element"].GetPtr();
  555. editParticleEffect.relative = element.checked;
  556. particleEffectEmitter.ApplyEffect();
  557. EndParticleEffectEdit();
  558. }
  559. bool ShowParticleEffectEditor()
  560. {
  561. RefreshParticleEffectEditor();
  562. particleEffectWindow.visible = true;
  563. particleEffectWindow.BringToFront();
  564. return true;
  565. }
  566. void HideParticleEffectEditor()
  567. {
  568. if (particleEffectWindow !is null)
  569. particleEffectWindow.visible = false;
  570. }
  571. void InitParticleEffectPreview()
  572. {
  573. particlePreviewScene = Scene("particlePreviewScene");
  574. particlePreviewScene.CreateComponent("Octree");
  575. Node@ zoneNode = particlePreviewScene.CreateChild("Zone");
  576. Zone@ zone = zoneNode.CreateComponent("Zone");
  577. zone.boundingBox = BoundingBox(-1000, 1000);
  578. zone.ambientColor = Color(0.15, 0.15, 0.15);
  579. zone.fogColor = Color(0, 0, 0);
  580. zone.fogStart = 10.0;
  581. zone.fogEnd = 100.0;
  582. particlePreviewCameraNode = particlePreviewScene.CreateChild("PreviewCamera");
  583. particlePreviewCameraNode.position = Vector3(0, 0, -2.5);
  584. Camera@ camera = particlePreviewCameraNode.CreateComponent("Camera");
  585. camera.nearClip = 0.1f;
  586. camera.farClip = 100.0f;
  587. particlePreviewLightNode = particlePreviewScene.CreateChild("particlePreviewLight");
  588. particlePreviewLightNode.direction = Vector3(0.5, -0.5, 0.5);
  589. particlePreviewLight = particlePreviewLightNode.CreateComponent("Light");
  590. particlePreviewLight.lightType = LIGHT_DIRECTIONAL;
  591. particlePreviewLight.specularIntensity = 0.5;
  592. particleEffectPreviewNode = particlePreviewScene.CreateChild("PreviewEmitter");
  593. particleEffectPreviewNode.rotation = Quaternion(0, 0, 0);
  594. StaticModel@ gizmo = particleEffectPreviewNode.CreateComponent("StaticModel");
  595. gizmo.model = cache.GetResource("Model", "Models/Editor/Axes.mdl");
  596. gizmo.materials[0] = cache.GetResource("Material", "Materials/Editor/RedUnlit.xml");
  597. gizmo.materials[1] = cache.GetResource("Material", "Materials/Editor/GreenUnlit.xml");
  598. gizmo.materials[2] = cache.GetResource("Material", "Materials/Editor/BlueUnlit.xml");
  599. gizmo.occludee = false;
  600. particleEffectEmitter = particleEffectPreviewNode.CreateComponent("ParticleEmitter");
  601. editParticleEffect = CreateNewParticleEffect();
  602. particleEffectEmitter.effect = editParticleEffect;
  603. particleEffectPreview = particleEffectWindow.GetChild("ParticleEffectPreview", true);
  604. particleEffectPreview.SetFixedHeight(100);
  605. particleEffectPreview.SetView(particlePreviewScene, camera);
  606. SubscribeToEvent(particleEffectPreview, "DragMove", "RotateParticleEffectPreview");
  607. }
  608. ParticleEffect@ CreateNewParticleEffect()
  609. {
  610. ParticleEffect@ effect = ParticleEffect();
  611. Material@ res = cache.GetResource("Material", "Materials/Particle.xml");
  612. if (res is null)
  613. log.Error("Could not load default material for new particle effect.");
  614. effect.material = res;
  615. effect.AddColorTime(Color(1,1,1,1), 0.0f);
  616. return effect;
  617. }
  618. void EditParticleEffect(ParticleEffect@ effect)
  619. {
  620. if (effect is null)
  621. return;
  622. if (editParticleEffect !is null)
  623. UnsubscribeFromEvent(editParticleEffect, "ReloadFinished");
  624. if (!effect.name.empty)
  625. cache.ReloadResource(effect);
  626. editParticleEffect = effect;
  627. particleEffectEmitter.effect = editParticleEffect;
  628. if (editParticleEffect !is null)
  629. SubscribeToEvent(editParticleEffect, "ReloadFinished", "RefreshParticleEffectEditor");
  630. ShowParticleEffectEditor();
  631. }
  632. void RefreshParticleEffectEditor()
  633. {
  634. inParticleEffectRefresh = true;
  635. RefreshParticleEffectPreview();
  636. RefreshParticleEffectName();
  637. RefreshParticleEffectBasicAttributes();
  638. RefreshParticleEffectMaterial();
  639. RefreshParticleEffectColorFrames();
  640. RefreshParticleEffectTextureFrames();
  641. inParticleEffectRefresh = false;
  642. }
  643. void RefreshParticleEffectColorFrames()
  644. {
  645. if (editParticleEffect is null)
  646. return;
  647. editParticleEffect.SortColorFrames();
  648. ListView@ lv = particleEffectWindow.GetChild("ColorFrameListView", true);
  649. if (lv is null)
  650. return;
  651. lv.RemoveAllItems();
  652. for (uint i = 0; i < editParticleEffect.numColorFrames; i++)
  653. {
  654. ColorFrame@ colorFrame = editParticleEffect.GetColorFrame(i);
  655. Button@ container = Button();
  656. lv.AddItem(container);
  657. container.style = "Button";
  658. container.imageRect = IntRect(18, 2, 30, 14);
  659. container.minSize = IntVector2(0, 20);
  660. container.maxSize = IntVector2(2147483647, 20);
  661. container.layoutMode = LM_HORIZONTAL;
  662. container.layoutBorder = IntRect(3,1,3,1);
  663. container.layoutSpacing = 4;
  664. UIElement@ labelContainer = UIElement();
  665. container.AddChild(labelContainer);
  666. labelContainer.style = "HorizontalPanel";
  667. labelContainer.minSize = IntVector2(0, 16);
  668. labelContainer.maxSize = IntVector2(2147483647, 16);
  669. labelContainer.verticalAlignment = VA_CENTER;
  670. {
  671. LineEdit@ le = LineEdit();
  672. labelContainer.AddChild(le);
  673. le.name = "ColorTime";
  674. le.vars["ColorFrame"] = i;
  675. le.style = "LineEdit";
  676. le.minSize = IntVector2(0, 16);
  677. le.maxSize = IntVector2(40, 16);
  678. le.text = colorFrame.time;
  679. le.cursorPosition = 0;
  680. CreateDragSlider(le);
  681. SubscribeToEvent(le, "TextChanged", "EditParticleEffectColorFrame");
  682. }
  683. UIElement@ textContainer = UIElement();
  684. labelContainer.AddChild(textContainer);
  685. textContainer.minSize = IntVector2(0, 16);
  686. textContainer.maxSize = IntVector2(2147483647, 16);
  687. textContainer.verticalAlignment = VA_CENTER;
  688. Text@ t = Text();
  689. textContainer.AddChild(t);
  690. t.style = "Text";
  691. t.text = "Color";
  692. UIElement@ editContainer = UIElement();
  693. container.AddChild(editContainer);
  694. editContainer.style = "HorizontalPanel";
  695. editContainer.minSize = IntVector2(0, 16);
  696. editContainer.maxSize = IntVector2(2147483647, 16);
  697. editContainer.verticalAlignment = VA_CENTER;
  698. {
  699. LineEdit@ le = LineEdit();
  700. editContainer.AddChild(le);
  701. le.name = "ColorR";
  702. le.vars["ColorFrame"] = i;
  703. le.style = "LineEdit";
  704. le.text = colorFrame.color.r;
  705. le.cursorPosition = 0;
  706. CreateDragSlider(le);
  707. SubscribeToEvent(le, "TextChanged", "EditParticleEffectColorFrame");
  708. }
  709. {
  710. LineEdit@ le = LineEdit();
  711. editContainer.AddChild(le);
  712. le.name = "ColorG";
  713. le.vars["ColorFrame"] = i;
  714. le.style = "LineEdit";
  715. le.text = colorFrame.color.g;
  716. le.cursorPosition = 0;
  717. CreateDragSlider(le);
  718. SubscribeToEvent(le, "TextChanged", "EditParticleEffectColorFrame");
  719. }
  720. {
  721. LineEdit@ le = LineEdit();
  722. editContainer.AddChild(le);
  723. le.name = "ColorB";
  724. le.vars["ColorFrame"] = i;
  725. le.style = "LineEdit";
  726. le.text = colorFrame.color.b;
  727. le.cursorPosition = 0;
  728. CreateDragSlider(le);
  729. SubscribeToEvent(le, "TextChanged", "EditParticleEffectColorFrame");
  730. }
  731. {
  732. LineEdit@ le = LineEdit();
  733. editContainer.AddChild(le);
  734. le.name = "ColorA";
  735. le.vars["ColorFrame"] = i;
  736. le.style = "LineEdit";
  737. le.text = colorFrame.color.a;
  738. le.cursorPosition = 0;
  739. CreateDragSlider(le);
  740. SubscribeToEvent(le, "TextChanged", "EditParticleEffectColorFrame");
  741. }
  742. }
  743. }
  744. void RefreshParticleEffectTextureFrames()
  745. {
  746. if (editParticleEffect is null)
  747. return;
  748. editParticleEffect.SortTextureFrames();
  749. ListView@ lv = particleEffectWindow.GetChild("TextureFrameListView", true);
  750. if (lv is null)
  751. return;
  752. lv.RemoveAllItems();
  753. for (uint i = 0; i < editParticleEffect.numTextureFrames; i++)
  754. {
  755. TextureFrame@ textureFrame = editParticleEffect.GetTextureFrame(i);
  756. if (textureFrame is null)
  757. continue;
  758. Button@ container = Button();
  759. lv.AddItem(container);
  760. container.style = "Button";
  761. container.imageRect = IntRect(18, 2, 30, 14);
  762. container.minSize = IntVector2(0, 20);
  763. container.maxSize = IntVector2(2147483647, 20);
  764. container.layoutMode = LM_HORIZONTAL;
  765. container.layoutBorder = IntRect(1,1,1,1);
  766. container.layoutSpacing = 4;
  767. UIElement@ labelContainer = UIElement();
  768. container.AddChild(labelContainer);
  769. labelContainer.style = "HorizontalPanel";
  770. labelContainer.minSize = IntVector2(0, 16);
  771. labelContainer.maxSize = IntVector2(2147483647, 16);
  772. labelContainer.verticalAlignment = VA_CENTER;
  773. {
  774. LineEdit@ le = LineEdit();
  775. labelContainer.AddChild(le);
  776. le.name = "TextureTime";
  777. le.vars["TextureFrame"] = i;
  778. le.style = "LineEdit";
  779. le.minSize = IntVector2(0, 16);
  780. le.maxSize = IntVector2(40, 16);
  781. le.text = textureFrame.time;
  782. le.cursorPosition = 0;
  783. CreateDragSlider(le);
  784. SubscribeToEvent(le, "TextChanged", "EditParticleEffectTextureFrame");
  785. }
  786. UIElement@ textContainer = UIElement();
  787. labelContainer.AddChild(textContainer);
  788. textContainer.minSize = IntVector2(0, 16);
  789. textContainer.maxSize = IntVector2(2147483647, 16);
  790. textContainer.verticalAlignment = VA_CENTER;
  791. Text@ t = Text();
  792. textContainer.AddChild(t);
  793. t.style = "Text";
  794. t.text = "Texture";
  795. UIElement@ editContainer = UIElement();
  796. container.AddChild(editContainer);
  797. editContainer.style = "HorizontalPanel";
  798. editContainer.minSize = IntVector2(0, 16);
  799. editContainer.maxSize = IntVector2(2147483647, 16);
  800. editContainer.verticalAlignment = VA_CENTER;
  801. {
  802. LineEdit@ le = LineEdit();
  803. editContainer.AddChild(le);
  804. le.name = "TextureMinX";
  805. le.vars["TextureFrame"] = i;
  806. le.style = "LineEdit";
  807. le.text = textureFrame.uv.min.x;
  808. le.cursorPosition = 0;
  809. CreateDragSlider(le);
  810. SubscribeToEvent(le, "TextChanged", "EditParticleEffectTextureFrame");
  811. }
  812. {
  813. LineEdit@ le = LineEdit();
  814. editContainer.AddChild(le);
  815. le.name = "TextureMinY";
  816. le.vars["TextureFrame"] = i;
  817. le.style = "LineEdit";
  818. le.text = textureFrame.uv.min.y;
  819. le.cursorPosition = 0;
  820. CreateDragSlider(le);
  821. SubscribeToEvent(le, "TextChanged", "EditParticleEffectTextureFrame");
  822. }
  823. {
  824. LineEdit@ le = LineEdit();
  825. editContainer.AddChild(le);
  826. le.name = "TextureMaxX";
  827. le.vars["TextureFrame"] = i;
  828. le.style = "LineEdit";
  829. le.text = textureFrame.uv.max.x;
  830. le.cursorPosition = 0;
  831. CreateDragSlider(le);
  832. SubscribeToEvent(le, "TextChanged", "EditParticleEffectTextureFrame");
  833. }
  834. {
  835. LineEdit@ le = LineEdit();
  836. editContainer.AddChild(le);
  837. le.name = "TextureMaxY";
  838. le.vars["TextureFrame"] = i;
  839. le.style = "LineEdit";
  840. le.text = textureFrame.uv.max.y;
  841. le.cursorPosition = 0;
  842. CreateDragSlider(le);
  843. SubscribeToEvent(le, "TextChanged", "EditParticleEffectTextureFrame");
  844. }
  845. }
  846. }
  847. void EditParticleEffectColorFrame(StringHash eventType, VariantMap& eventData)
  848. {
  849. if (inParticleEffectRefresh)
  850. return;
  851. if (editParticleEffect is null)
  852. return;
  853. if (particleEffectEmitter is null)
  854. return;
  855. BeginParticleEffectEdit();
  856. LineEdit@ element = eventData["Element"].GetPtr();
  857. uint i = element.vars["ColorFrame"].GetInt();
  858. ColorFrame@ cf = editParticleEffect.GetColorFrame(i);
  859. if (element.name == "ColorTime")
  860. cf.time = element.text.ToFloat();
  861. if (element.name == "ColorR")
  862. cf.color = Color(element.text.ToFloat(), cf.color.g, cf.color.b, cf.color.a);
  863. if (element.name == "ColorG")
  864. cf.color = Color(cf.color.r, element.text.ToFloat(), cf.color.b, cf.color.a);
  865. if (element.name == "ColorB")
  866. cf.color = Color(cf.color.r, cf.color.g, element.text.ToFloat(), cf.color.a);
  867. if (element.name == "ColorA")
  868. cf.color = Color(cf.color.r, cf.color.g, cf.color.b, element.text.ToFloat());
  869. editParticleEffect.SetColorFrame(i, cf);
  870. particleEffectEmitter.Reset();
  871. EndParticleEffectEdit();
  872. }
  873. void EditParticleEffectTextureFrame(StringHash eventType, VariantMap& eventData)
  874. {
  875. if (inParticleEffectRefresh)
  876. return;
  877. if (editParticleEffect is null)
  878. return;
  879. if (particleEffectEmitter is null)
  880. return;
  881. BeginParticleEffectEdit();
  882. LineEdit@ element = eventData["Element"].GetPtr();
  883. uint i = element.vars["TextureFrame"].GetInt();
  884. TextureFrame@ tf = editParticleEffect.GetTextureFrame(i);
  885. if (element.name == "TextureTime")
  886. tf.time = element.text.ToFloat();
  887. if (element.name == "TextureMinX")
  888. tf.uv = Rect(element.text.ToFloat(), tf.uv.min.y, tf.uv.max.x, tf.uv.max.y);
  889. if (element.name == "TextureMinY")
  890. tf.uv = Rect(tf.uv.min.x, element.text.ToFloat(), tf.uv.max.x, tf.uv.max.y);
  891. if (element.name == "TextureMaxX")
  892. tf.uv = Rect(tf.uv.min.x, tf.uv.min.y, element.text.ToFloat(), tf.uv.max.y);
  893. if (element.name == "TextureMaxY")
  894. tf.uv = Rect(tf.uv.min.x, tf.uv.min.y, tf.uv.max.x, element.text.ToFloat());
  895. editParticleEffect.SetTextureFrame(i, tf);
  896. particleEffectEmitter.Reset();
  897. EndParticleEffectEdit();
  898. }
  899. void RefreshParticleEffectPreview()
  900. {
  901. if (particleEffectEmitter is null || editParticleEffect is null)
  902. return;
  903. particleEffectEmitter.effect = editParticleEffect;
  904. particleEffectEmitter.Reset();
  905. particleEffectPreview.QueueUpdate();
  906. }
  907. void RefreshParticleEffectName()
  908. {
  909. UIElement@ container = particleEffectWindow.GetChild("NameContainer", true);
  910. if (container is null)
  911. return;
  912. container.RemoveAllChildren();
  913. LineEdit@ nameEdit = CreateAttributeLineEdit(container, null, 0, 0);
  914. if (editParticleEffect !is null)
  915. nameEdit.text = editParticleEffect.name;
  916. SubscribeToEvent(nameEdit, "TextFinished", "EditParticleEffectName");
  917. Button@ pickButton = CreateResourcePickerButton(container, null, 0, 0, "Pick");
  918. SubscribeToEvent(pickButton, "Released", "PickEditParticleEffect");
  919. }
  920. void RefreshParticleEffectBasicAttributes()
  921. {
  922. if (editParticleEffect is null)
  923. return;
  924. cast<LineEdit>(particleEffectWindow.GetChild("ConstantForceX", true)).text = editParticleEffect.constantForce.x;
  925. cast<LineEdit>(particleEffectWindow.GetChild("ConstantForceY", true)).text = editParticleEffect.constantForce.y;
  926. cast<LineEdit>(particleEffectWindow.GetChild("ConstantForceZ", true)).text = editParticleEffect.constantForce.z;
  927. cast<LineEdit>(particleEffectWindow.GetChild("DirectionMinX", true)).text = editParticleEffect.minDirection.x;
  928. cast<LineEdit>(particleEffectWindow.GetChild("DirectionMinY", true)).text = editParticleEffect.minDirection.y;
  929. cast<LineEdit>(particleEffectWindow.GetChild("DirectionMinZ", true)).text = editParticleEffect.minDirection.z;
  930. cast<LineEdit>(particleEffectWindow.GetChild("DirectionMaxX", true)).text = editParticleEffect.maxDirection.x;
  931. cast<LineEdit>(particleEffectWindow.GetChild("DirectionMaxY", true)).text = editParticleEffect.maxDirection.y;
  932. cast<LineEdit>(particleEffectWindow.GetChild("DirectionMaxZ", true)).text = editParticleEffect.maxDirection.z;
  933. cast<LineEdit>(particleEffectWindow.GetChild("DampingForce", true)).text = editParticleEffect.dampingForce;
  934. cast<LineEdit>(particleEffectWindow.GetChild("ActiveTime", true)).text = editParticleEffect.activeTime;
  935. cast<LineEdit>(particleEffectWindow.GetChild("InactiveTime", true)).text = editParticleEffect.inactiveTime;
  936. cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMinX", true)).text = editParticleEffect.minParticleSize.x;
  937. cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMinY", true)).text = editParticleEffect.minParticleSize.y;
  938. cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMaxX", true)).text = editParticleEffect.maxParticleSize.x;
  939. cast<LineEdit>(particleEffectWindow.GetChild("ParticleSizeMaxY", true)).text = editParticleEffect.maxParticleSize.y;
  940. cast<LineEdit>(particleEffectWindow.GetChild("TimeToLiveMin", true)).text = editParticleEffect.minTimeToLive;
  941. cast<LineEdit>(particleEffectWindow.GetChild("TimeToLiveMax", true)).text = editParticleEffect.maxTimeToLive;
  942. cast<LineEdit>(particleEffectWindow.GetChild("VelocityMin", true)).text = editParticleEffect.minVelocity;
  943. cast<LineEdit>(particleEffectWindow.GetChild("VelocityMax", true)).text = editParticleEffect.maxVelocity;
  944. cast<LineEdit>(particleEffectWindow.GetChild("RotationMin", true)).text = editParticleEffect.minRotation;
  945. cast<LineEdit>(particleEffectWindow.GetChild("RotationMax", true)).text = editParticleEffect.maxRotation;
  946. cast<LineEdit>(particleEffectWindow.GetChild("RotationSpeedMin", true)).text = editParticleEffect.minRotationSpeed;
  947. cast<LineEdit>(particleEffectWindow.GetChild("RotationSpeedMax", true)).text = editParticleEffect.maxRotationSpeed;
  948. cast<LineEdit>(particleEffectWindow.GetChild("SizeAdd", true)).text = editParticleEffect.sizeAdd;
  949. cast<LineEdit>(particleEffectWindow.GetChild("SizeMultiply", true)).text = editParticleEffect.sizeMul;
  950. cast<LineEdit>(particleEffectWindow.GetChild("AnimationLodBias", true)).text = editParticleEffect.animationLodBias;
  951. cast<LineEdit>(particleEffectWindow.GetChild("NumParticles", true)).text = editParticleEffect.numParticles;
  952. cast<LineEdit>(particleEffectWindow.GetChild("EmitterSizeX", true)).text = editParticleEffect.emitterSize.x;
  953. cast<LineEdit>(particleEffectWindow.GetChild("EmitterSizeY", true)).text = editParticleEffect.emitterSize.y;
  954. cast<LineEdit>(particleEffectWindow.GetChild("EmitterSizeZ", true)).text = editParticleEffect.emitterSize.z;
  955. cast<LineEdit>(particleEffectWindow.GetChild("EmissionRateMin", true)).text = editParticleEffect.minEmissionRate;
  956. cast<LineEdit>(particleEffectWindow.GetChild("EmissionRateMax", true)).text = editParticleEffect.maxEmissionRate;
  957. switch (editParticleEffect.emitterType)
  958. {
  959. case EMITTER_BOX:
  960. cast<DropDownList>(particleEffectWindow.GetChild("EmitterShape", true)).selection = 0;
  961. break;
  962. case EMITTER_SPHERE:
  963. cast<DropDownList>(particleEffectWindow.GetChild("EmitterShape", true)).selection = 1;
  964. break;
  965. }
  966. cast<CheckBox>(particleEffectWindow.GetChild("Scaled", true)).checked = editParticleEffect.scaled;
  967. cast<CheckBox>(particleEffectWindow.GetChild("Sorted", true)).checked = editParticleEffect.sorted;
  968. cast<CheckBox>(particleEffectWindow.GetChild("Relative", true)).checked = editParticleEffect.relative;
  969. }
  970. void RefreshParticleEffectMaterial()
  971. {
  972. UIElement@ container = particleEffectWindow.GetChild("ParticleMaterialContainer", true);
  973. if (container is null)
  974. return;
  975. container.RemoveAllChildren();
  976. LineEdit@ nameEdit = CreateAttributeLineEdit(container, null, 0, 0);
  977. if (editParticleEffect !is null)
  978. {
  979. if (editParticleEffect.material !is null)
  980. nameEdit.text = editParticleEffect.material.name;
  981. else
  982. {
  983. nameEdit.text = "Materials/Particle.xml";
  984. Material@ res = cache.GetResource("Material", "Materials/Particle.xml");
  985. if (res !is null)
  986. editParticleEffect.material = res;
  987. }
  988. }
  989. SubscribeToEvent(nameEdit, "TextFinished", "EditParticleEffectMaterial");
  990. Button@ pickButton = CreateResourcePickerButton(container, null, 0, 0, "Pick");
  991. SubscribeToEvent(pickButton, "Released", "PickEditParticleEffectMaterial");
  992. }
  993. void RotateParticleEffectPreview(StringHash eventType, VariantMap& eventData)
  994. {
  995. int elemX = eventData["ElementX"].GetInt();
  996. int elemY = eventData["ElementY"].GetInt();
  997. if (particleEffectPreview.height > 0 && particleEffectPreview.width > 0)
  998. {
  999. float yaw = ((particleEffectPreview.height / 2) - elemY) * (90.0 / particleEffectPreview.height);
  1000. float pitch = ((particleEffectPreview.width / 2) - elemX) * (90.0 / particleEffectPreview.width);
  1001. particleEffectPreviewNode.rotation = particleEffectPreviewNode.rotation.Slerp(Quaternion(yaw, pitch, 0), 0.1);
  1002. particleEffectPreview.QueueUpdate();
  1003. }
  1004. }
  1005. void EditParticleEffectName(StringHash eventType, VariantMap& eventData)
  1006. {
  1007. LineEdit@ nameEdit = eventData["Element"].GetPtr();
  1008. String newParticleEffectName = nameEdit.text.Trimmed();
  1009. if (!newParticleEffectName.empty && !(editParticleEffect !is null && newParticleEffectName == editParticleEffect.name))
  1010. {
  1011. ParticleEffect@ newParticleEffect = cache.GetResource("ParticleEffect", newParticleEffectName);
  1012. if (newParticleEffect !is null)
  1013. EditParticleEffect(newParticleEffect);
  1014. }
  1015. }
  1016. void PickEditParticleEffect()
  1017. {
  1018. @resourcePicker = GetResourcePicker(StringHash("ParticleEffect"));
  1019. if (resourcePicker is null)
  1020. return;
  1021. String lastPath = resourcePicker.lastPath;
  1022. if (lastPath.empty)
  1023. lastPath = sceneResourcePath;
  1024. CreateFileSelector("Pick " + resourcePicker.typeName, "OK", "Cancel", lastPath, resourcePicker.filters, resourcePicker.lastFilter);
  1025. SubscribeToEvent(uiFileSelector, "FileSelected", "PickEditParticleEffectDone");
  1026. }
  1027. void PickEditParticleEffectDone(StringHash eventType, VariantMap& eventData)
  1028. {
  1029. StoreResourcePickerPath();
  1030. CloseFileSelector();
  1031. if (!eventData["OK"].GetBool())
  1032. {
  1033. @resourcePicker = null;
  1034. return;
  1035. }
  1036. String resourceName = eventData["FileName"].GetString();
  1037. Resource@ res = GetPickedResource(resourceName);
  1038. if (res !is null)
  1039. EditParticleEffect(cast<ParticleEffect>(res));
  1040. @resourcePicker = null;
  1041. }
  1042. void NewParticleEffect()
  1043. {
  1044. BeginParticleEffectEdit();
  1045. EditParticleEffect(CreateNewParticleEffect());
  1046. EndParticleEffectEdit();
  1047. }
  1048. void RevertParticleEffect()
  1049. {
  1050. if (inParticleEffectRefresh)
  1051. return;
  1052. if (editParticleEffect is null)
  1053. return;
  1054. if (editParticleEffect.name.empty)
  1055. {
  1056. NewParticleEffect();
  1057. return;
  1058. }
  1059. BeginParticleEffectEdit();
  1060. cache.ReloadResource(editParticleEffect);
  1061. EndParticleEffectEdit();
  1062. RefreshParticleEffectEditor();
  1063. }
  1064. void SaveParticleEffect()
  1065. {
  1066. if (editParticleEffect is null || editParticleEffect.name.empty)
  1067. return;
  1068. String fullName = cache.GetResourceFileName(editParticleEffect.name);
  1069. if (fullName.empty)
  1070. return;
  1071. File saveFile(fullName, FILE_WRITE);
  1072. editParticleEffect.Save(saveFile);
  1073. }
  1074. void SaveParticleEffectAs()
  1075. {
  1076. if (editParticleEffect is null)
  1077. return;
  1078. @resourcePicker = GetResourcePicker(StringHash("ParticleEffect"));
  1079. if (resourcePicker is null)
  1080. return;
  1081. String lastPath = resourcePicker.lastPath;
  1082. if (lastPath.empty)
  1083. lastPath = sceneResourcePath;
  1084. CreateFileSelector("Save particle effect as", "Save", "Cancel", lastPath, resourcePicker.filters, resourcePicker.lastFilter);
  1085. SubscribeToEvent(uiFileSelector, "FileSelected", "SaveParticleEffectAsDone");
  1086. }
  1087. void SaveParticleEffectAsDone(StringHash eventType, VariantMap& eventData)
  1088. {
  1089. StoreResourcePickerPath();
  1090. CloseFileSelector();
  1091. @resourcePicker = null;
  1092. if (editParticleEffect is null)
  1093. return;
  1094. if (!eventData["OK"].GetBool())
  1095. {
  1096. @resourcePicker = null;
  1097. return;
  1098. }
  1099. String fullName = eventData["FileName"].GetString();
  1100. // Add default extension for saving if not specified
  1101. String filter = eventData["Filter"].GetString();
  1102. if (GetExtension(fullName).empty && filter != "*.*")
  1103. fullName = fullName + filter.Substring(1);
  1104. File saveFile(fullName, FILE_WRITE);
  1105. if (editParticleEffect.Save(saveFile))
  1106. {
  1107. saveFile.Close();
  1108. // Load the new resource to update the name in the editor
  1109. ParticleEffect@ newEffect = cache.GetResource("ParticleEffect", GetResourceNameFromFullName(fullName));
  1110. if (newEffect !is null)
  1111. EditParticleEffect(newEffect);
  1112. }
  1113. }
  1114. void BeginParticleEffectEdit()
  1115. {
  1116. if (editParticleEffect is null)
  1117. return;
  1118. inParticleEffectRefresh = true;
  1119. oldParticleEffectState = XMLFile();
  1120. XMLElement particleElem = oldParticleEffectState.CreateRoot("particleeffect");
  1121. editParticleEffect.Save(particleElem);
  1122. }
  1123. void EndParticleEffectEdit()
  1124. {
  1125. if (editParticleEffect is null)
  1126. return;
  1127. if (!dragEditAttribute)
  1128. {
  1129. EditParticleEffectAction@ action = EditParticleEffectAction();
  1130. action.Define(particleEffectEmitter, editParticleEffect, oldParticleEffectState);
  1131. SaveEditAction(action);
  1132. }
  1133. inParticleEffectRefresh = false;
  1134. particleEffectPreview.QueueUpdate();
  1135. }