TDME2  1.9.200
ParticleSystemEditorTabController.cpp
Go to the documentation of this file.
2 
3 #include <memory>
4 #include <string>
5 
6 #include <tdme/tdme.h>
22 #include <tdme/engine/Engine.h>
23 #include <tdme/engine/Rotation.h>
24 #include <tdme/engine/Transform.h>
30 #include <tdme/gui/nodes/GUINode.h>
34 #include <tdme/gui/GUI.h>
35 #include <tdme/gui/GUIParser.h>
36 #include <tdme/math/Math.h>
37 #include <tdme/math/Matrix4x4.h>
38 #include <tdme/math/Vector3.h>
55 #include <tdme/utilities/Action.h>
56 #include <tdme/utilities/Console.h>
59 #include <tdme/utilities/Float.h>
60 #include <tdme/utilities/Integer.h>
63 
64 using std::make_unique;
65 using std::string;
66 using std::unique_ptr;
67 
69 
96 using tdme::math::Math;
123 
124 ParticleSystemEditorTabController::ParticleSystemEditorTabController(ParticleSystemEditorTabView* view)
125 {
126  this->view = view;
127  this->popUps = view->getPopUps();
128  this->basePropertiesSubController = make_unique<BasePropertiesSubController>(view->getEditorView(), "prototype");
129  this->prototypePhysicsSubController = make_unique<PrototypePhysicsSubController>(view->getEditorView(), view, false);
130  this->prototypeDisplaySubController = make_unique<PrototypeDisplaySubController>(view->getEditorView(), view, prototypePhysicsSubController->getView());
131  this->prototypeSoundsSubController = make_unique<PrototypeSoundsSubController>(view->getEditorView(), view);
132  this->prototypeScriptSubController = make_unique<PrototypeScriptSubController>(view->getEditorView());
133 }
134 
136 }
137 
139 {
140  this->screenNode = screenNode;
147 }
148 
150 {
151 }
152 
154 {
155  switch (command) {
156  case COMMAND_SAVE:
157  {
158  auto fileName = view->getPrototype() != nullptr?view->getPrototype()->getFileName():"";
159  try {
160  if (fileName.empty() == true) throw ExceptionBase("Could not save file. No filename known");
161  view->saveFile(
162  Tools::getPathName(fileName),
163  Tools::getFileName(fileName)
164  );
165  } catch (Exception& exception) {
166  showInfoPopUp("Warning", string(exception.what()));
167  }
168  }
169  break;
170  case COMMAND_SAVEAS:
171  {
172  class OnParticleSave: public virtual Action
173  {
174  public:
175  void performAction() override {
176  try {
177  particleSystemEditorTabController->view->saveFile(
178  particleSystemEditorTabController->popUps->getFileDialogScreenController()->getPathName(),
179  particleSystemEditorTabController->popUps->getFileDialogScreenController()->getFileName()
180  );
181  } catch (Exception& exception) {
182  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
183  }
184  particleSystemEditorTabController->popUps->getFileDialogScreenController()->close();
185  }
186  OnParticleSave(ParticleSystemEditorTabController* particleSystemEditorTabController): particleSystemEditorTabController(particleSystemEditorTabController) {
187  }
188  private:
189  ParticleSystemEditorTabController* particleSystemEditorTabController;
190  };
191 
192  auto fileName = view->getPrototype() != nullptr?view->getPrototype()->getFileName():"";
194  fileName.empty() == false?Tools::getPathName(fileName):string(),
195  "Save to: ",
196  {{ "tparticle" }},
197  Tools::getFileName(fileName),
198  false,
199  new OnParticleSave(this)
200  );
201  }
202  break;
203  default:
204  showInfoPopUp("Warning", "This command is not supported yet");
205  break;
206  }
207 }
208 
209 void ParticleSystemEditorTabController::onDrop(const string& payload, int mouseX, int mouseY) {
210  if (prototypeSoundsSubController->onDrop(payload, mouseX, mouseY, view->getPrototype()) == true) return;
211  if (prototypePhysicsSubController->onDrop(payload, mouseX, mouseY, view->getPrototype()) == true) return;
212  if (prototypeScriptSubController->onDrop(payload, mouseX, mouseY, view->getPrototype()) == true) return;
213  if (StringTools::startsWith(payload, "file:") == false) {
214  showInfoPopUp("Warning", "Unknown payload in drop");
215  } else {
216  auto fileName = StringTools::substring(payload, string("file:").size());
217  if (view->getEditorView()->getScreenController()->isDropOnNode(mouseX, mouseY, "particletype_point_texture") == true) {
218  if (Tools::hasFileExtension(fileName, TextureReader::getTextureExtensions()) == false) {
219  showInfoPopUp("Warning", "You can not drop this file here. Allowed file extensions are " + Tools::enumerateFileExtensions(TextureReader::getTextureExtensions()));
220  } else {
221  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
222  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
223  setPointParticleSystemTexture(particleSystemIdx, fileName);
224  }
225  } else
226  if (view->getEditorView()->getScreenController()->isDropOnNode(mouseX, mouseY, "particletype_point_transparency") == true) {
227  if (Tools::hasFileExtension(fileName, TextureReader::getTextureExtensions()) == false) {
228  showInfoPopUp("Warning", "You can not drop this file here. Allowed file extensions are " + Tools::enumerateFileExtensions(TextureReader::getTextureExtensions()));
229  } else {
230  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
231  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
232  setPointParticleSystemTransparencyTexture(particleSystemIdx, fileName);
233  }
234  } else
235  if (view->getEditorView()->getScreenController()->isDropOnNode(mouseX, mouseY, "particletype_fog_texture") == true) {
236  if (Tools::hasFileExtension(fileName, TextureReader::getTextureExtensions()) == false) {
237  showInfoPopUp("Warning", "You can not drop this file here. Allowed file extensions are " + Tools::enumerateFileExtensions(TextureReader::getTextureExtensions()));
238  } else {
239  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
240  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
241  setFogParticleSystemTexture(particleSystemIdx, fileName);
242  }
243  } else
244  if (view->getEditorView()->getScreenController()->isDropOnNode(mouseX, mouseY, "particletype_fog_transparency") == true) {
245  if (Tools::hasFileExtension(fileName, TextureReader::getTextureExtensions()) == false) {
246  showInfoPopUp("Warning", "You can not drop this file here. Allowed file extensions are " + Tools::enumerateFileExtensions(TextureReader::getTextureExtensions()));
247  } else {
248  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
249  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
250  setFogParticleSystemTransparencyTexture(particleSystemIdx, fileName);
251  }
252  } else
253  if (view->getEditorView()->getScreenController()->isDropOnNode(mouseX, mouseY, "particletype_object") == true) {
254  if (Tools::hasFileExtension(fileName, ModelReader::getModelExtensions()) == false) {
255  showInfoPopUp("Warning", "You can not drop this file here. Allowed file extensions are " + Tools::enumerateFileExtensions(ModelReader::getModelExtensions()));
256  } else {
257  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
258  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
259  setObjectParticleSystemModel(particleSystemIdx, fileName);
260  }
261  } else {
262  showInfoPopUp("Warning", "You can not drop a file here");
263  }
264  }
265 }
266 
268  required_dynamic_cast<GUITextNode*>(screenNode->getNodeById(view->getTabId() + "_tab_text_info"))->setText(text);
269 }
270 
271 void ParticleSystemEditorTabController::showInfoPopUp(const string& caption, const string& message)
272 {
273  popUps->getInfoDialogScreenController()->show(caption, message);
274 }
275 
277 {
278  if (basePropertiesSubController->onChange(node, view->getPrototype(), view->getPrototype()) == true) return;
279  if (prototypeDisplaySubController->onChange(node, view->getPrototype()) == true) return;
280  if (prototypePhysicsSubController->onChange(node, view->getPrototype()) == true) return;
281  if (prototypeSoundsSubController->onChange(node, view->getPrototype(), nullptr) == true) return;
282  if (prototypeScriptSubController->onChange(node, view->getPrototype()) == true) return;
283  //
284  if (node->getId() == "dropdown_outliner_add") {
285  if (node->getController()->getValue().getString() == "particlesystem") {
286  // TODO: move me into a method as I am using it also in context menu, too lazy right now :D
287  auto prototype = view->getPrototype();
288  if (prototype != nullptr) {
289  prototype->addParticleSystem(new PrototypeParticleSystem());
290  auto particleSystemIdx = prototype->getParticleSystemsCount() - 1;
291  if (particleSystemIdx != -1) {
293  view->getEditorView()->reloadTabOutliner("particlesystems." + to_string(particleSystemIdx));
295  }
296  }
297  }
298  } else
299  if (node->getId() == "selectbox_outliner") {
300  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
301  if (StringTools::startsWith(view->getEditorView()->getScreenController()->getOutlinerSelection(), "particlesystems.") == true) {
302  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
303  view->setParticleSystemIndex(particleSystemIdx, false);
304  } else {
305  view->setParticleSystemIndex(-1, false);
306  }
307  updateDetails(outlinerNode);
308  } else {
309  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
310  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
311  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
312  for (const auto& applyOPSNode: applyOPSNodes) {
313  if (node->getId() == applyOPSNode) {
314  applyParticleSystemDetails(particleSystemIdx);
315  break;
316  }
317  }
318  for (const auto& applyPPSNode: applyPPSNodes) {
319  if (node->getId() == applyPPSNode) {
320  applyParticleSystemDetails(particleSystemIdx);
321  break;
322  }
323  }
324  for (const auto& applyFPSNode: applyFPSNodes) {
325  if (node->getId() == applyFPSNode) {
326  applyParticleSystemDetails(particleSystemIdx);
327  break;
328  }
329  }
330  for (const auto& applyBaseNode: applyBaseNodes) {
331  if (node->getId() == applyBaseNode) {
332  applyParticleSystemDetails(particleSystemIdx);
333  break;
334  }
335  }
336  for (const auto& applyBBPENode: applyBBPENodes) {
337  if (node->getId() == applyBBPENode) {
338  applyParticleSystemDetails(particleSystemIdx);
339  break;
340  }
341  }
342  for (const auto& applyPPENode: applyPPENodes) {
343  if (node->getId() == applyPPENode) {
344  applyParticleSystemDetails(particleSystemIdx);
345  break;
346  }
347  }
348  for (const auto& applySPENode: applySPENodes) {
349  if (node->getId() == applySPENode) {
350  applyParticleSystemDetails(particleSystemIdx);
351  break;
352  }
353  }
354  for (const auto& applyCPENode: applyCPENodes) {
355  if (node->getId() == applyCPENode) {
356  applyParticleSystemDetails(particleSystemIdx);
357  break;
358  }
359  }
360  for (const auto& applyRPENode: applyRPENodes) {
361  if (node->getId() == applyRPENode) {
362  applyParticleSystemDetails(particleSystemIdx);
363  break;
364  }
365  }
366  }
367  }
368 }
369 
371  if (basePropertiesSubController->onFocus(node, view->getPrototype()) == true) return;
372  if (prototypeSoundsSubController->onFocus(node, view->getPrototype()) == true) return;
373 }
374 
376  if (basePropertiesSubController->onUnfocus(node, view->getPrototype()) == true) return;
377  if (prototypeSoundsSubController->onUnfocus(node, view->getPrototype()) == true) return;
378 }
379 
381 
382  basePropertiesSubController->onContextMenuRequest(node, mouseX, mouseY, view->getPrototype());
383  prototypePhysicsSubController->onContextMenuRequest(node, mouseX, mouseY, view->getPrototype());
384  prototypeSoundsSubController->onContextMenuRequest(node, mouseX, mouseY, view->getPrototype());
385  if (node->getId() == "selectbox_outliner") {
386  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
387  if (outlinerNode == "particlesystems") {
388  // clear
390 
391  // delete
392  class OnAddParticleSystemAction: public virtual Action
393  {
394  public:
395  void performAction() override {
396  auto prototype = particleSystemEditorTabController->view->getPrototype();
397  if (prototype == nullptr) return;
398  prototype->addParticleSystem(new PrototypeParticleSystem());
399  auto particleSystemIdx = prototype->getParticleSystemsCount() - 1;
400  //
401  auto view = particleSystemEditorTabController->view;
403  auto editorView = particleSystemEditorTabController->view->getEditorView();
404  editorView->reloadTabOutliner("particlesystems." + to_string(particleSystemIdx));
406  }
407  OnAddParticleSystemAction(ParticleSystemEditorTabController* particleSystemEditorTabController): particleSystemEditorTabController(particleSystemEditorTabController) {
408  }
409  private:
410  ParticleSystemEditorTabController* particleSystemEditorTabController;
411  };
412  popUps->getContextMenuScreenController()->addMenuItem("Add Particle System", "contextmenu_add", new OnAddParticleSystemAction(this));
413 
414  //
415  popUps->getContextMenuScreenController()->show(mouseX, mouseY);
416  } else
417  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
418  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
419 
420  // clear
422 
423  // delete
424  class OnRemoveParticleSystemAction: public virtual Action
425  {
426  public:
427  void performAction() override {
428  auto prototype = particleSystemEditorTabController->view->getPrototype();
429  if (prototype == nullptr) return;
430  //
431  prototype->removeParticleSystemAt(particleSystemIdx);
432  //
433  particleSystemEditorTabController->view->uninitParticleSystem();
434  auto editorView = particleSystemEditorTabController->view->getEditorView();
435  editorView->reloadTabOutliner("particlesystems");
436  particleSystemEditorTabController->view->initParticleSystem();
437  }
438  OnRemoveParticleSystemAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
439  }
440  private:
441  ParticleSystemEditorTabController* particleSystemEditorTabController;
442  int particleSystemIdx;
443  };
444  popUps->getContextMenuScreenController()->addMenuItem("Remove Particle System", "contextmenu_remove", new OnRemoveParticleSystemAction(this, particleSystemIdx));
445 
446  //
447  popUps->getContextMenuScreenController()->show(mouseX, mouseY);
448  }
449  }
450 }
451 
453  int tooltipLeft, tooltipTop;
454  if (view->getEditorView()->getCurrentTabTooltipPosition(screenNode, mouseX, mouseY, tooltipLeft, tooltipTop) == false) return;
455  //
456  popUps->getTooltipScreenController()->show(tooltipLeft, tooltipTop, node->getToolTip());
457 }
458 
461 }
462 
464 {
465  auto prototype = view->getPrototype();
466  if (prototype == nullptr) return;
467  //
468  if (basePropertiesSubController->onAction(type, node, prototype) == true) return;
469  if (prototypeDisplaySubController->onAction(type, node, prototype) == true) return;
470  if (prototypePhysicsSubController->onAction(type, node, prototype) == true) return;
471  if (prototypeSoundsSubController->onAction(type, node, prototype) == true) return;
472  if (prototypeScriptSubController->onAction(type, node, prototype) == true) return;
473  //
474  if (type == GUIActionListenerType::PERFORMED) {
475  if (node->getId().compare("particleemitter_box_colorstart_edit") == 0) {
476  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
477  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
478  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
479  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
480  auto bbpe = particleSystem != nullptr?particleSystem->getBoundingBoxParticleEmitters():nullptr;
481  if (bbpe != nullptr) {
482  //
483  class OnColorChangeAction: public virtual Action
484  {
485  public:
486  void performAction() override {
487  auto prototype = particleSystemEditorTabController->view->getPrototype();
488  if (prototype == nullptr) return;
489  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
490  auto bbpe = particleSystem != nullptr?particleSystem->getBoundingBoxParticleEmitters():nullptr;
491  if (bbpe == nullptr) return;
492  bbpe->setColorStart(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
493  //
494  try {
495  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_box_colorstart"))->setEffectColorMul(bbpe->getColorStart());
496  } catch (Exception& exception) {
497  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
498  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
499  }
500  particleSystemEditorTabController->view->initParticleSystem();
501  }
502  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
503  }
504  private:
505  ParticleSystemEditorTabController* particleSystemEditorTabController;
506  int particleSystemIdx;
507  };
508  popUps->getColorPickerScreenController()->show(bbpe->getColorStart(), new OnColorChangeAction(this, particleSystemIdx));
509  }
510  }
511  } else
512  if (node->getId().compare("particleemitter_box_colorend_edit") == 0) {
513  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
514  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
515  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
516  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
517  auto bbpe = particleSystem != nullptr?particleSystem->getBoundingBoxParticleEmitters():nullptr;
518  if (bbpe != nullptr) {
519  //
520  class OnColorChangeAction: public virtual Action
521  {
522  public:
523  void performAction() override {
524  auto prototype = particleSystemEditorTabController->view->getPrototype();
525  if (prototype == nullptr) return;
526  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
527  auto bbpe = particleSystem != nullptr?particleSystem->getBoundingBoxParticleEmitters():nullptr;
528  if (bbpe == nullptr) return;
529  bbpe->setColorEnd(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
530  //
531  try {
532  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_box_colorend"))->setEffectColorMul(bbpe->getColorEnd());
533  } catch (Exception& exception) {
534  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
535  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
536  }
537  particleSystemEditorTabController->view->initParticleSystem();
538  }
539  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
540  }
541  private:
542  ParticleSystemEditorTabController* particleSystemEditorTabController;
543  int particleSystemIdx;
544  };
545  popUps->getColorPickerScreenController()->show(bbpe->getColorEnd(), new OnColorChangeAction(this, particleSystemIdx));
546  }
547  }
548  } else
549  if (node->getId().compare("particleemitter_point_colorstart_edit") == 0) {
550  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
551  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
552  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
553  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
554  auto ppe = particleSystem != nullptr?particleSystem->getPointParticleEmitter():nullptr;
555  if (ppe != nullptr) {
556  //
557  class OnColorChangeAction: public virtual Action
558  {
559  public:
560  void performAction() override {
561  auto prototype = particleSystemEditorTabController->view->getPrototype();
562  if (prototype == nullptr) return;
563  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
564  auto ppe = particleSystem != nullptr?particleSystem->getPointParticleEmitter():nullptr;
565  if (ppe == nullptr) return;
566  ppe->setColorStart(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
567  //
568  try {
569  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_point_colorstart"))->setEffectColorMul(ppe->getColorStart());
570  } catch (Exception& exception) {
571  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
572  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
573  }
574  particleSystemEditorTabController->view->initParticleSystem();
575  }
576  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
577  }
578  private:
579  ParticleSystemEditorTabController* particleSystemEditorTabController;
580  int particleSystemIdx;
581  };
582  popUps->getColorPickerScreenController()->show(ppe->getColorStart(), new OnColorChangeAction(this, particleSystemIdx));
583  }
584  }
585  } else
586  if (node->getId().compare("particleemitter_point_colorend_edit") == 0) {
587  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
588  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
589  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
590  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
591  auto ppe = particleSystem != nullptr?particleSystem->getPointParticleEmitter():nullptr;
592  if (ppe != nullptr) {
593  //
594  class OnColorChangeAction: public virtual Action
595  {
596  public:
597  void performAction() override {
598  auto prototype = particleSystemEditorTabController->view->getPrototype();
599  if (prototype == nullptr) return;
600  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
601  auto ppe = particleSystem != nullptr?particleSystem->getPointParticleEmitter():nullptr;
602  if (ppe == nullptr) return;
603  ppe->setColorEnd(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
604  //
605  try {
606  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_point_colorend"))->setEffectColorMul(ppe->getColorEnd());
607  } catch (Exception& exception) {
608  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
609  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
610  }
611  particleSystemEditorTabController->view->initParticleSystem();
612  }
613  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
614  }
615  private:
616  ParticleSystemEditorTabController* particleSystemEditorTabController;
617  int particleSystemIdx;
618  };
619  popUps->getColorPickerScreenController()->show(ppe->getColorEnd(), new OnColorChangeAction(this, particleSystemIdx));
620  }
621  }
622  } else
623  if (node->getId().compare("particleemitter_sphere_colorstart_edit") == 0) {
624  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
625  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
626  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
627  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
628  auto spe = particleSystem != nullptr?particleSystem->getSphereParticleEmitter():nullptr;
629  if (spe != nullptr) {
630  //
631  class OnColorChangeAction: public virtual Action
632  {
633  public:
634  void performAction() override {
635  auto prototype = particleSystemEditorTabController->view->getPrototype();
636  if (prototype == nullptr) return;
637  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
638  auto spe = particleSystem != nullptr?particleSystem->getSphereParticleEmitter():nullptr;
639  if (spe == nullptr) return;
640  spe->setColorStart(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
641  //
642  try {
643  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_sphere_colorstart"))->setEffectColorMul(spe->getColorStart());
644  } catch (Exception& exception) {
645  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
646  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
647  }
648  particleSystemEditorTabController->view->initParticleSystem();
649  }
650  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
651  }
652  private:
653  ParticleSystemEditorTabController* particleSystemEditorTabController;
654  int particleSystemIdx;
655  };
656  popUps->getColorPickerScreenController()->show(spe->getColorStart(), new OnColorChangeAction(this, particleSystemIdx));
657  }
658  }
659  } else
660  if (node->getId().compare("particleemitter_sphere_colorend_edit") == 0) {
661  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
662  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
663  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
664  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
665  auto spe = particleSystem != nullptr?particleSystem->getSphereParticleEmitter():nullptr;
666  if (spe != nullptr) {
667  //
668  class OnColorChangeAction: public virtual Action
669  {
670  public:
671  void performAction() override {
672  auto prototype = particleSystemEditorTabController->view->getPrototype();
673  if (prototype == nullptr) return;
674  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
675  auto spe = particleSystem != nullptr?particleSystem->getSphereParticleEmitter():nullptr;
676  if (spe == nullptr) return;
677  spe->setColorEnd(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
678  //
679  try {
680  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_sphere_colorend"))->setEffectColorMul(spe->getColorEnd());
681  } catch (Exception& exception) {
682  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
683  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
684  }
685  particleSystemEditorTabController->view->initParticleSystem();
686  }
687  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
688  }
689  private:
690  ParticleSystemEditorTabController* particleSystemEditorTabController;
691  int particleSystemIdx;
692  };
693  popUps->getColorPickerScreenController()->show(spe->getColorEnd(), new OnColorChangeAction(this, particleSystemIdx));
694  }
695  }
696  }
697  if (node->getId().compare("particleemitter_circle_colorstart_edit") == 0) {
698  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
699  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
700  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
701  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
702  auto cpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitter():nullptr;
703  if (cpe != nullptr) {
704  //
705  class OnColorChangeAction: public virtual Action
706  {
707  public:
708  void performAction() override {
709  auto prototype = particleSystemEditorTabController->view->getPrototype();
710  if (prototype == nullptr) return;
711  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
712  auto cpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitter():nullptr;
713  if (cpe == nullptr) return;
714  cpe->setColorStart(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
715  //
716  try {
717  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_circle_colorstart"))->setEffectColorMul(cpe->getColorStart());
718  } catch (Exception& exception) {
719  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
720  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
721  }
722  particleSystemEditorTabController->view->initParticleSystem();
723  }
724  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
725  }
726  private:
727  ParticleSystemEditorTabController* particleSystemEditorTabController;
728  int particleSystemIdx;
729  };
730  popUps->getColorPickerScreenController()->show(cpe->getColorStart(), new OnColorChangeAction(this, particleSystemIdx));
731  }
732  }
733  } else
734  if (node->getId().compare("particleemitter_circle_colorend_edit") == 0) {
735  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
736  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
737  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
738  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
739  auto cpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitter():nullptr;
740  if (cpe != nullptr) {
741  //
742  class OnColorChangeAction: public virtual Action
743  {
744  public:
745  void performAction() override {
746  auto prototype = particleSystemEditorTabController->view->getPrototype();
747  if (prototype == nullptr) return;
748  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
749  auto cpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitter():nullptr;
750  if (cpe == nullptr) return;
751  cpe->setColorEnd(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
752  //
753  try {
754  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_circle_colorend"))->setEffectColorMul(cpe->getColorEnd());
755  } catch (Exception& exception) {
756  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
757  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
758  }
759  particleSystemEditorTabController->view->initParticleSystem();
760  }
761  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
762  }
763  private:
764  ParticleSystemEditorTabController* particleSystemEditorTabController;
765  int particleSystemIdx;
766  };
767  popUps->getColorPickerScreenController()->show(cpe->getColorEnd(), new OnColorChangeAction(this, particleSystemIdx));
768  }
769  }
770  } else
771  if (node->getId().compare("particleemitter_radial_colorstart_edit") == 0) {
772  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
773  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
774  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
775  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
776  auto rpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitterPlaneVelocity():nullptr;
777  if (rpe != nullptr) {
778  //
779  class OnColorChangeAction: public virtual Action
780  {
781  public:
782  void performAction() override {
783  auto prototype = particleSystemEditorTabController->view->getPrototype();
784  if (prototype == nullptr) return;
785  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
786  auto rpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitterPlaneVelocity():nullptr;
787  if (rpe == nullptr) return;
788  rpe->setColorStart(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
789  //
790  try {
791  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_radial_colorstart"))->setEffectColorMul(rpe->getColorStart());
792  } catch (Exception& exception) {
793  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
794  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
795  }
796  particleSystemEditorTabController->view->initParticleSystem();
797  }
798  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
799  }
800  private:
801  ParticleSystemEditorTabController* particleSystemEditorTabController;
802  int particleSystemIdx;
803  };
804  popUps->getColorPickerScreenController()->show(rpe->getColorStart(), new OnColorChangeAction(this, particleSystemIdx));
805  }
806  }
807  } else
808  if (node->getId().compare("particleemitter_radial_colorend_edit") == 0) {
809  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
810  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
811  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
812  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
813  auto rpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitterPlaneVelocity():nullptr;
814  if (rpe != nullptr) {
815  //
816  class OnColorChangeAction: public virtual Action
817  {
818  public:
819  void performAction() override {
820  auto prototype = particleSystemEditorTabController->view->getPrototype();
821  if (prototype == nullptr) return;
822  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
823  auto rpe = particleSystem != nullptr?particleSystem->getCircleParticleEmitterPlaneVelocity():nullptr;
824  if (rpe == nullptr) return;
825  rpe->setColorEnd(Color4(particleSystemEditorTabController->popUps->getColorPickerScreenController()->getColor()));
826  //
827  try {
828  required_dynamic_cast<GUIImageNode*>(particleSystemEditorTabController->screenNode->getNodeById("particleemitter_radial_colorend"))->setEffectColorMul(rpe->getColorEnd());
829  } catch (Exception& exception) {
830  Console::println("OnColorChangeAction::performAction(): An error occurred: " + string(exception.what()));
831  particleSystemEditorTabController->showInfoPopUp("Warning", string(exception.what()));
832  }
833  particleSystemEditorTabController->view->initParticleSystem();
834  }
835  OnColorChangeAction(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx): particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
836  }
837  private:
838  ParticleSystemEditorTabController* particleSystemEditorTabController;
839  int particleSystemIdx;
840  };
841  popUps->getColorPickerScreenController()->show(rpe->getColorEnd(), new OnColorChangeAction(this, particleSystemIdx));
842  }
843  }
844  } else
845  if (node->getId().compare("particletype_point_texture_open") == 0) {
846  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
847  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
848  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
849  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
850  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
851  if (pps != nullptr) {
852  class OnPointParticleSystemLoadTexture: public virtual Action
853  {
854  public:
855  void performAction() override {
856  particleSystemEditorTabController->setPointParticleSystemTexture(
857  particleSystemIdx,
858  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getPathName() + "/" + particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getFileName()
859  );
860  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->close();
861  }
862 
863  OnPointParticleSystemLoadTexture(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx)
864  : particleSystemEditorTabController(particleSystemEditorTabController)
865  , particleSystemIdx(particleSystemIdx) {
866  }
867  private:
868  ParticleSystemEditorTabController* particleSystemEditorTabController;
869  int particleSystemIdx;
870  };
871 
873  pps->getTextureFileName().empty() == false?Tools::getPathName(pps->getTextureFileName()):string(),
874  "Load point particle system texture from: ",
875  TextureReader::getTextureExtensions(),
876  Tools::getFileName(pps->getTextureFileName()),
877  true,
878  new OnPointParticleSystemLoadTexture(this, particleSystemIdx)
879  );
880  }
881  }
882  } else
883  if (node->getId().compare("particletype_point_texture_remove") == 0) {
884  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
885  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
886  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
887  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
888  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
889  if (pps != nullptr) {
891  try {
892  pps->setTextureFileName(string(), pps->getTransparencyTextureFileName());
893  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_texture"))->setSource(pps->getTextureFileName());
894  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_texture"))->setTooltip(pps->getTextureFileName());
895  } catch (Exception& exception) {
896  Console::println("ParticleSystemEditorTabController::onAction(): An error occurred: " + string(exception.what()));
897  showInfoPopUp("Warning", string(exception.what()));
898  }
900  }
901  }
902  } else
903  if (node->getId().compare("particletype_point_texture_browseto") == 0) {
904  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
905  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
906  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
907  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
908  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
909  if (pps != nullptr && pps->getTextureFileName().empty() == false) {
910  view->getEditorView()->getScreenController()->browseTo(pps->getTextureFileName());
911  } else {
912  showInfoPopUp("Browse To", "Nothing to browse to");
913  }
914  }
915  } else
916  if (node->getId().compare("particletype_point_transparency_open") == 0) {
917  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
918  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
919  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
920  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
921  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
922  if (pps != nullptr) {
923  class OnPointParticleSystemLoadTransparencyTexture: public virtual Action
924  {
925  public:
926  void performAction() override {
927  particleSystemEditorTabController->setPointParticleSystemTransparencyTexture(
928  particleSystemIdx,
929  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getPathName() + "/" + particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getFileName()
930  );
931  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->close();
932  }
933 
934  OnPointParticleSystemLoadTransparencyTexture(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx)
935  : particleSystemEditorTabController(particleSystemEditorTabController)
936  , particleSystemIdx(particleSystemIdx) {
937  }
938  private:
939  ParticleSystemEditorTabController* particleSystemEditorTabController;
940  int particleSystemIdx;
941  };
942 
944  pps->getTextureFileName().empty() == false?Tools::getPathName(pps->getTextureFileName()):string(),
945  "Load point particle system texture from: ",
946  TextureReader::getTextureExtensions(),
947  Tools::getFileName(pps->getTextureFileName()),
948  true,
949  new OnPointParticleSystemLoadTransparencyTexture(this, particleSystemIdx)
950  );
951  }
952  }
953  } else
954  if (node->getId().compare("particletype_point_transparency_remove") == 0) {
955  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
956  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
957  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
958  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
959  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
960  if (pps != nullptr) {
962  try {
963  pps->setTextureFileName(pps->getTextureFileName(), string());
964  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_transparency"))->setSource(pps->getTransparencyTextureFileName());
965  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_transparency"))->setTooltip(pps->getTransparencyTextureFileName());
966  } catch (Exception& exception) {
967  Console::println("ParticleSystemEditorTabController::onAction(): An error occurred: " + string(exception.what()));
968  showInfoPopUp("Warning", string(exception.what()));
969  }
971  }
972  }
973  } else
974  if (node->getId().compare("particletype_point_transparency_browseto") == 0) {
975  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
976  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
977  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
978  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
979  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
980  if (pps != nullptr && pps->getTransparencyTextureFileName().empty() == false) {
981  view->getEditorView()->getScreenController()->browseTo(pps->getTransparencyTextureFileName());
982  } else {
983  showInfoPopUp("Browse To", "Nothing to browse to");
984  }
985  }
986  } else
987  if (node->getId().compare("particletype_fog_texture_open") == 0) {
988  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
989  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
990  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
991  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
992  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
993  if (fps != nullptr) {
994  class OnFogParticleSystemLoadTexture: public virtual Action
995  {
996  public:
997  void performAction() override {
998  particleSystemEditorTabController->setFogParticleSystemTexture(
999  particleSystemIdx,
1000  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getPathName() + "/" + particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getFileName()
1001  );
1002  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->close();
1003  }
1004 
1005  OnFogParticleSystemLoadTexture(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx)
1006  : particleSystemEditorTabController(particleSystemEditorTabController)
1007  , particleSystemIdx(particleSystemIdx) {
1008  }
1009  private:
1010  ParticleSystemEditorTabController* particleSystemEditorTabController;
1011  int particleSystemIdx;
1012  };
1013 
1015  fps->getTextureFileName().empty() == false?Tools::getPathName(fps->getTextureFileName()):string(),
1016  "Load point particle system texture from: ",
1017  TextureReader::getTextureExtensions(),
1018  Tools::getFileName(fps->getTextureFileName()),
1019  true,
1020  new OnFogParticleSystemLoadTexture(this, particleSystemIdx)
1021  );
1022  }
1023  }
1024  } else
1025  if (node->getId().compare("particletype_fog_texture_remove") == 0) {
1026  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1027  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1028  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1029  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1030  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1031  if (fps != nullptr) {
1033  try {
1034  fps->setTextureFileName(string(), fps->getTransparencyTextureFileName());
1035  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_texture"))->setSource(fps->getTextureFileName());
1036  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_texture"))->setTooltip(fps->getTextureFileName());
1037  } catch (Exception& exception) {
1038  Console::println("ParticleSystemEditorTabController::onAction(): An error occurred: " + string(exception.what()));
1039  showInfoPopUp("Warning", string(exception.what()));
1040  }
1042  }
1043  }
1044  } else
1045  if (node->getId().compare("particletype_fog_texture_browseto") == 0) {
1046  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1047  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1048  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1049  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1050  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1051  if (fps != nullptr && fps->getTextureFileName().empty() == false) {
1052  view->getEditorView()->getScreenController()->browseTo(fps->getTextureFileName());
1053  } else {
1054  showInfoPopUp("Browse To", "Nothing to browse to");
1055  }
1056  }
1057  } else
1058  if (node->getId().compare("particletype_fog_transparency_open") == 0) {
1059  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1060  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1061  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1062  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1063  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1064  if (fps != nullptr) {
1065  class OnFogParticleSystemLoadTransparencyTexture: public virtual Action
1066  {
1067  public:
1068  void performAction() override {
1069  particleSystemEditorTabController->setFogParticleSystemTransparencyTexture(
1070  particleSystemIdx,
1071  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getPathName() + "/" + particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getFileName()
1072  );
1073  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->close();
1074  }
1075 
1076  OnFogParticleSystemLoadTransparencyTexture(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx)
1077  : particleSystemEditorTabController(particleSystemEditorTabController)
1078  , particleSystemIdx(particleSystemIdx) {
1079  }
1080  private:
1081  ParticleSystemEditorTabController* particleSystemEditorTabController;
1082  int particleSystemIdx;
1083  };
1084 
1086  fps->getTextureFileName().empty() == false?Tools::getPathName(fps->getTextureFileName()):string(),
1087  "Load point particle system texture from: ",
1088  TextureReader::getTextureExtensions(),
1089  Tools::getFileName(fps->getTextureFileName()),
1090  true,
1091  new OnFogParticleSystemLoadTransparencyTexture(this, particleSystemIdx)
1092  );
1093  }
1094  }
1095  } else
1096  if (node->getId().compare("particletype_fog_transparency_remove") == 0) {
1097  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1098  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1099  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1100  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1101  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1102  if (fps != nullptr) {
1104  try {
1105  fps->setTextureFileName(fps->getTextureFileName(), string());
1106  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_transparency"))->setSource(fps->getTransparencyTextureFileName());
1107  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_transparency"))->setTooltip(fps->getTransparencyTextureFileName());
1108  } catch (Exception& exception) {
1109  Console::println("ParticleSystemEditorTabController::onAction(): An error occurred: " + string(exception.what()));
1110  showInfoPopUp("Warning", string(exception.what()));
1111  }
1113  }
1114  }
1115  } else
1116  if (node->getId().compare("particletype_fog_transparency_browseto") == 0) {
1117  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1118  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1119  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1120  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1121  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1122  if (fps != nullptr && fps->getTransparencyTextureFileName().empty() == false) {
1123  view->getEditorView()->getScreenController()->browseTo(fps->getTransparencyTextureFileName());
1124  } else {
1125  showInfoPopUp("Browse To", "Nothing to browse to");
1126  }
1127  }
1128  } else
1129  if (node->getId() == "particletype_object_open") {
1130  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1131  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1132  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1133  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1134  auto ops = particleSystem != nullptr?particleSystem->getObjectParticleSystem():nullptr;
1135  if (ops != nullptr) {
1136  //
1137  class OnObjectParticleSystemLoadModel: public virtual Action
1138  {
1139  public:
1140  void performAction() override {
1141  particleSystemEditorTabController->setObjectParticleSystemModel(
1142  particleSystemIdx,
1143  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getPathName() + "/" + particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->getFileName()
1144  );
1145  particleSystemEditorTabController->view->getPopUps()->getFileDialogScreenController()->close();
1146  }
1147 
1148  OnObjectParticleSystemLoadModel(ParticleSystemEditorTabController* particleSystemEditorTabController, int particleSystemIdx)
1149  : particleSystemEditorTabController(particleSystemEditorTabController), particleSystemIdx(particleSystemIdx) {
1150  //
1151  }
1152 
1153  private:
1154  ParticleSystemEditorTabController* particleSystemEditorTabController;
1155  int particleSystemIdx;
1156  };
1157 
1158  //
1160  ops->getModelFileName().empty() == false?Tools::getPathName(ops->getModelFileName()):string(),
1161  "Load object particle system model from: ",
1162  ModelReader::getModelExtensions(),
1163  string(),
1164  true,
1165  new OnObjectParticleSystemLoadModel(this, particleSystemIdx)
1166  );
1167  }
1168  }
1169  } else
1170  if (node->getId() == "particletype_object_remove") {
1171  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1172  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1173  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1174  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1175  auto ops = particleSystem != nullptr?particleSystem->getObjectParticleSystem():nullptr;
1176  if (ops == nullptr) return;
1178  try {
1179  ops->setModelFile(string());
1180  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_object"))->setSource(ops->getModelFileName());
1181  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_object"))->setTooltip(ops->getModelFileName());
1182  } catch (Exception& exception) {
1183  Console::println("ParticleSystemEditorTabController::onAction(): An error occurred: " + string(exception.what()));
1184  showInfoPopUp("Warning", string(exception.what()));
1185  }
1187  }
1188  } else
1189  if (node->getId() == "particletype_object_browseto") {
1190  auto outlinerNode = view->getEditorView()->getScreenController()->getOutlinerSelection();
1191  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1192  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1193  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1194  auto ops = particleSystem != nullptr?particleSystem->getObjectParticleSystem():nullptr;
1195  if (ops != nullptr && ops->getModelFileName().empty() == false) {
1196  view->getEditorView()->getScreenController()->browseTo(ops->getModelFileName());
1197  } else {
1198  showInfoPopUp("Browse To", "Nothing to browse to");
1199  }
1201  }
1202  }
1203  }
1204 }
1205 
1207  string xml;
1208  xml+= "<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape("Prototype") + "\" value=\"" + GUIParser::escape("prototype") + "\">\n";
1209  auto prototype = view->getPrototype();
1210  if (prototype != nullptr) {
1211  basePropertiesSubController->createBasePropertiesXML(prototype, xml);
1212  prototypeScriptSubController->createScriptXML(prototype, xml);
1213  prototypePhysicsSubController->createOutlinerPhysicsXML(prototype, xml);
1214  prototypeSoundsSubController->createOutlinerSoundsXML(prototype, xml);
1215  //
1216  if (prototype->getParticleSystemsCount() == 0) {
1217  xml+= "<selectbox-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape("Particle Systems") + "\" value=\"" + GUIParser::escape("particlesystems") + "\" />\n";
1218  } else {
1219  xml+= "<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape("Particle Systems") + "\" value=\"" + GUIParser::escape("particlesystems") + "\">\n";
1220  auto i = 0;
1221  for (auto particleSystem: prototype->getParticleSystems()) {
1222  xml+= " <selectbox-option image=\"resources/engine/images/particle.png\" text=\"" + GUIParser::escape("Particle System " + to_string(i)) + "\" id=\"" + GUIParser::escape("particlesystems." + to_string(i)) + "\" value=\"" + GUIParser::escape("particlesystems." + to_string(i)) + "\" />\n";
1223  i++;
1224  }
1225  xml+= "</selectbox-parent-option>\n";
1226  }
1227  }
1228  xml+= "</selectbox-parent-option>\n";
1230 }
1231 
1234  string("<dropdown-option text=\"Property\" value=\"property\" />\n") +
1235  string("<dropdown-option text=\"BV\" value=\"boundingvolume\" />\n") +
1236  string("<dropdown-option text=\"PS\" value=\"particlesystem\" />\n") +
1237  string("<dropdown-option text=\"Sound\" value=\"sound\" />\n")
1238  );
1239 }
1240 
1242  auto prototype = view->getPrototype();
1243  if (prototype == nullptr) return;
1244  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1245  if (particleSystem == nullptr) return;
1246 
1248  string("<template id=\"details_particletype\" src=\"resources/engine/gui/template_details_particletype.xml\" />\n") +
1249  string("<template id=\"details_particleemitter\" src=\"resources/engine/gui/template_details_particleemitter.xml\" />\n")
1250  );
1251 
1252  //
1253  try {
1254  //
1255  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("details_particletype"))->getActiveConditions().add("open");
1256 
1257  //
1258  if (particleSystem->getType() == PrototypeParticleSystem_Type::NONE) {
1259  } else
1260  if (particleSystem->getType() == PrototypeParticleSystem_Type::OBJECT_PARTICLE_SYSTEM) {
1261  auto ops = particleSystem->getObjectParticleSystem();
1262  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type"))->getController()->setValue(MutableString(1));
1263  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type_details"))->getActiveConditions().set("object");
1264  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_object"))->setSource(ops->getModelFileName());
1265  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_object"))->setTooltip(ops->getModelFileName());
1266  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_object_scale"))->getController()->setValue(MutableString(Math::max(ops->getScale().getX(), Math::max(ops->getScale().getY(), ops->getScale().getZ()))));
1267  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_object_maxcount"))->getController()->setValue(MutableString(ops->getMaxCount()));
1268  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_object_autoemit"))->getController()->setValue(MutableString(ops->isAutoEmit() == true?"1":""));
1269  } else
1270  if (particleSystem->getType() == PrototypeParticleSystem_Type::POINT_PARTICLE_SYSTEM) {
1271  auto pps = particleSystem->getPointParticleSystem();
1272  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type"))->getController()->setValue(MutableString(2));
1273  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type_details"))->getActiveConditions().set("point");
1274  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_texture"))->setSource(pps->getTextureFileName());
1275  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_texture"))->setTooltip(pps->getTextureFileName());
1276  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_transparency"))->setSource(pps->getTransparencyTextureFileName());
1277  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_transparency"))->setTooltip(pps->getTransparencyTextureFileName());
1278  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_size"))->getController()->setValue(MutableString(pps->getPointSize()));
1279  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_maxcount"))->getController()->setValue(MutableString(pps->getMaxPoints()));
1280  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_horizontal_sprites"))->getController()->setValue(MutableString(pps->getTextureHorizontalSprites()));
1281  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_vertical_sprites"))->getController()->setValue(MutableString(pps->getTextureVerticalSprites()));
1282  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_fps"))->getController()->setValue(MutableString(pps->getTextureSpritesFPS()));
1283  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_autoemit"))->getController()->setValue(MutableString(pps->isAutoEmit() == true?"1":""));
1284  } else
1285  if (particleSystem->getType() == PrototypeParticleSystem_Type::FOG_PARTICLE_SYSTEM) {
1286  auto fps = particleSystem->getFogParticleSystem();
1287  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type"))->getController()->setValue(MutableString(3));
1288  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type_details"))->getActiveConditions().set("fog");
1289  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_texture"))->setSource(fps->getTextureFileName());
1290  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_texture"))->setTooltip(fps->getTextureFileName());
1291  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_transparency"))->setSource(fps->getTransparencyTextureFileName());
1292  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_transparency"))->setTooltip(fps->getTransparencyTextureFileName());
1293  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_size"))->getController()->setValue(MutableString(fps->getPointSize()));
1294  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_maxcount"))->getController()->setValue(MutableString(fps->getMaxPoints()));
1295  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_horizontal_sprites"))->getController()->setValue(MutableString(fps->getTextureHorizontalSprites()));
1296  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_vertical_sprites"))->getController()->setValue(MutableString(fps->getTextureVerticalSprites()));
1297  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_fps"))->getController()->setValue(MutableString(fps->getTextureSpritesFPS()));
1298  } else {
1299  Console::println("ParticleSystemEditorTabController::setParticleSystemDetails(): Unknown particle system type");
1300  }
1301 
1302  //
1303  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("details_particleemitter"))->getActiveConditions().add("open");
1304 
1305  //
1306  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::POINT_PARTICLE_EMITTER) {
1307  auto ppse = particleSystem->getPointParticleEmitter();
1308  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(1));
1309  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("point");
1310  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_x"))->getController()->setValue(MutableString(ppse->getPosition().getX()));
1311  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_y"))->getController()->setValue(MutableString(ppse->getPosition().getY()));
1312  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_z"))->getController()->setValue(MutableString(ppse->getPosition().getZ()));
1313  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_point_colorstart"))->setEffectColorMul(ppse->getColorStart());
1314  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_point_colorend"))->setEffectColorMul(ppse->getColorEnd());
1315  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_count"))->getController()->setValue(MutableString(ppse->getCount()));
1316  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_lifetime_min"))->getController()->setValue(MutableString(static_cast<int32_t>(ppse->getLifeTime())));
1317  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_lifetime_max"))->getController()->setValue(MutableString(static_cast<int32_t>(ppse->getLifeTime() + ppse->getLifeTimeRnd())));
1318  auto velocityMax = ppse->getVelocity().clone().add(ppse->getVelocityRnd());
1319  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_min_x"))->getController()->setValue(MutableString(ppse->getVelocity().getX()));
1320  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_min_y"))->getController()->setValue(MutableString(ppse->getVelocity().getY()));
1321  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_min_z"))->getController()->setValue(MutableString(ppse->getVelocity().getZ()));
1322  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_max_x"))->getController()->setValue(MutableString(velocityMax.getX()));
1323  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_max_y"))->getController()->setValue(MutableString(velocityMax.getY()));
1324  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_max_z"))->getController()->setValue(MutableString(velocityMax.getZ()));
1325  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_mass_min"))->getController()->setValue(MutableString(static_cast<int32_t>(ppse->getMass())));
1326  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_mass_max"))->getController()->setValue(MutableString(static_cast<int32_t>(ppse->getMass() + ppse->getMassRnd())));
1327  } else
1328  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::BOUNDINGBOX_PARTICLE_EMITTER) {
1329  auto bbpe = particleSystem->getBoundingBoxParticleEmitters();
1330 
1331  Matrix4x4 rotationMatrix;
1332  rotationMatrix.identity();
1333  rotationMatrix.setAxes(bbpe->getObbAxis0(), bbpe->getObbAxis1(), bbpe->getObbAxis2());
1334  auto rotation = rotationMatrix.computeEulerAngles();
1335 
1336  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(2));
1337  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("box");
1338  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_x"))->getController()->setValue(MutableString(bbpe->getObbCenter().getX()));
1339  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_y"))->getController()->setValue(MutableString(bbpe->getObbCenter().getY()));
1340  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_z"))->getController()->setValue(MutableString(bbpe->getObbCenter().getZ()));
1341  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_x"))->getController()->setValue(MutableString(rotation.getX()));
1342  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_y"))->getController()->setValue(MutableString(rotation.getY()));
1343  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_z"))->getController()->setValue(MutableString(rotation.getZ()));
1344  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_x"))->getController()->setValue(MutableString(bbpe->getObbHalfextension().getX()));
1345  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_y"))->getController()->setValue(MutableString(bbpe->getObbHalfextension().getY()));
1346  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_z"))->getController()->setValue(MutableString(bbpe->getObbHalfextension().getZ()));
1347  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_box_colorstart"))->setEffectColorMul(bbpe->getColorStart());
1348  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_box_colorend"))->setEffectColorMul(bbpe->getColorEnd());
1349  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_count"))->getController()->setValue(MutableString(bbpe->getCount()));
1350  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_lifetime_min"))->getController()->setValue(MutableString(static_cast<int32_t>(bbpe->getLifeTime())));
1351  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_lifetime_max"))->getController()->setValue(MutableString(static_cast<int32_t>(bbpe->getLifeTime() + bbpe->getLifeTimeRnd())));
1352  auto velocityMax = bbpe->getVelocity().clone().add(bbpe->getVelocityRnd());
1353  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_min_x"))->getController()->setValue(MutableString(bbpe->getVelocity().getX()));
1354  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_min_y"))->getController()->setValue(MutableString(bbpe->getVelocity().getY()));
1355  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_min_z"))->getController()->setValue(MutableString(bbpe->getVelocity().getZ()));
1356  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_max_x"))->getController()->setValue(MutableString(velocityMax.getX()));
1357  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_max_y"))->getController()->setValue(MutableString(velocityMax.getY()));
1358  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_max_z"))->getController()->setValue(MutableString(velocityMax.getZ()));
1359  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_mass_min"))->getController()->setValue(MutableString(static_cast<int32_t>(bbpe->getMass())));
1360  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_mass_max"))->getController()->setValue(MutableString(static_cast<int32_t>(bbpe->getMass() + bbpe->getMassRnd())));
1361  } else
1362  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER) {
1363  auto cpse = particleSystem->getCircleParticleEmitter();
1364 
1365  Matrix4x4 rotationMatrix;
1366  rotationMatrix.identity();
1367  rotationMatrix.setAxes(cpse->getAxis0(), Vector3::computeCrossProduct(cpse->getAxis0(), cpse->getAxis1()), cpse->getAxis1());
1368  auto rotation = rotationMatrix.computeEulerAngles();
1369 
1370  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(3));
1371  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("circle");
1372  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_x"))->getController()->setValue(MutableString(cpse->getCenter().getX()));
1373  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_y"))->getController()->setValue(MutableString(cpse->getCenter().getY()));
1374  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_z"))->getController()->setValue(MutableString(cpse->getCenter().getZ()));
1375  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_x"))->getController()->setValue(MutableString(rotation.getX()));
1376  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_y"))->getController()->setValue(MutableString(rotation.getY()));
1377  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_z"))->getController()->setValue(MutableString(rotation.getZ()));
1378  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_radius"))->getController()->setValue(MutableString(cpse->getRadius()));
1379  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_circle_colorstart"))->setEffectColorMul(cpse->getColorStart());
1380  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_circle_colorend"))->setEffectColorMul(cpse->getColorEnd());
1381  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_count"))->getController()->setValue(MutableString(cpse->getCount()));
1382  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_lifetime_min"))->getController()->setValue(MutableString(static_cast<int32_t>(cpse->getLifeTime())));
1383  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_lifetime_max"))->getController()->setValue(MutableString(static_cast<int32_t>(cpse->getLifeTime() + cpse->getLifeTimeRnd())));
1384  auto velocityMax = cpse->getVelocity().clone().add(cpse->getVelocityRnd());
1385  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_min_x"))->getController()->setValue(MutableString(cpse->getVelocity().getX()));
1386  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_min_y"))->getController()->setValue(MutableString(cpse->getVelocity().getY()));
1387  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_min_z"))->getController()->setValue(MutableString(cpse->getVelocity().getZ()));
1388  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_max_x"))->getController()->setValue(MutableString(velocityMax.getX()));
1389  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_max_y"))->getController()->setValue(MutableString(velocityMax.getY()));
1390  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_max_z"))->getController()->setValue(MutableString(velocityMax.getZ()));
1391  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_mass_min"))->getController()->setValue(MutableString(static_cast<int32_t>(cpse->getMass())));
1392  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_mass_max"))->getController()->setValue(MutableString(static_cast<int32_t>(cpse->getMass() + cpse->getMassRnd())));
1393  } else
1394  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER_PLANE_VELOCITY) {
1395  auto rpse = particleSystem->getCircleParticleEmitterPlaneVelocity();
1396 
1397  Matrix4x4 rotationMatrix;
1398  rotationMatrix.identity();
1399  rotationMatrix.setAxes(rpse->getAxis0(), Vector3::computeCrossProduct(rpse->getAxis0(), rpse->getAxis1()), rpse->getAxis1());
1400  auto rotation = rotationMatrix.computeEulerAngles();
1401 
1402  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(4));
1403  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("radial");
1404  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_x"))->getController()->setValue(MutableString(rpse->getCenter().getX()));
1405  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_y"))->getController()->setValue(MutableString(rpse->getCenter().getY()));
1406  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_z"))->getController()->setValue(MutableString(rpse->getCenter().getZ()));
1407  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_x"))->getController()->setValue(MutableString(rotation.getX()));
1408  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_y"))->getController()->setValue(MutableString(rotation.getY()));
1409  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_z"))->getController()->setValue(MutableString(rotation.getZ()));
1410  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_radius"))->getController()->setValue(MutableString(rpse->getRadius()));
1411  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_radial_colorstart"))->setEffectColorMul(rpse->getColorStart());
1412  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_radial_colorend"))->setEffectColorMul(rpse->getColorEnd());
1413  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_count"))->getController()->setValue(MutableString(rpse->getCount()));
1414  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_lifetime_min"))->getController()->setValue(MutableString(static_cast<int32_t>(rpse->getLifeTime())));
1415  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_lifetime_max"))->getController()->setValue(MutableString(static_cast<int32_t>(rpse->getLifeTime() + rpse->getLifeTimeRnd())));
1416  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_velocity_min"))->getController()->setValue(MutableString(rpse->getVelocity()));
1417  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_velocity_max"))->getController()->setValue(MutableString(rpse->getVelocity() + rpse->getVelocityRnd()));
1418  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_mass_min"))->getController()->setValue(MutableString(static_cast<int32_t>(rpse->getMass())));
1419  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_mass_max"))->getController()->setValue(MutableString(static_cast<int32_t>(rpse->getMass() + rpse->getMassRnd())));
1420  } else
1421  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::SPHERE_PARTICLE_EMITTER) {
1422  auto spse = particleSystem->getSphereParticleEmitter();
1423  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(5));
1424  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("sphere");
1425  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_x"))->getController()->setValue(MutableString(spse->getCenter().getX()));
1426  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_y"))->getController()->setValue(MutableString(spse->getCenter().getY()));
1427  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_z"))->getController()->setValue(MutableString(spse->getCenter().getZ()));
1428  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_radius"))->getController()->setValue(MutableString(spse->getRadius()));
1429  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_sphere_colorstart"))->setEffectColorMul(spse->getColorStart());
1430  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particleemitter_sphere_colorend"))->setEffectColorMul(spse->getColorEnd());
1431  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_count"))->getController()->setValue(MutableString(spse->getCount()));
1432  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_lifetime_min"))->getController()->setValue(MutableString(static_cast<int32_t>(spse->getLifeTime())));
1433  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_lifetime_max"))->getController()->setValue(MutableString(static_cast<int32_t>(spse->getLifeTime() + spse->getLifeTimeRnd())));
1434  auto velocityMax = spse->getVelocity().clone().add(spse->getVelocityRnd());
1435  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_min_x"))->getController()->setValue(MutableString(spse->getVelocity().getX()));
1436  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_min_y"))->getController()->setValue(MutableString(spse->getVelocity().getY()));
1437  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_min_z"))->getController()->setValue(MutableString(spse->getVelocity().getZ()));
1438  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_max_x"))->getController()->setValue(MutableString(velocityMax.getX()));
1439  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_max_y"))->getController()->setValue(MutableString(velocityMax.getY()));
1440  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_max_z"))->getController()->setValue(MutableString(velocityMax.getZ()));
1441  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_mass_min"))->getController()->setValue(MutableString(static_cast<int32_t>(spse->getMass())));
1442  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_mass_max"))->getController()->setValue(MutableString(static_cast<int32_t>(spse->getMass() + spse->getMassRnd())));
1443  } else {
1444  Console::println("ParticleSystemEditorTabController::applyParticleSystemDetails(): unknown emitter");
1445  }
1446  } catch (Exception& exception) {
1447  Console::println("ParticleSystemEditorTabController::setParticleSystemDetails(): An error occurred: " + string(exception.what()));
1448  showInfoPopUp("Warning", string(exception.what()));
1449  }
1450 }
1451 
1453  Console::println("ParticleSystemEditorTabController::applyParticleSystemDetails(): xxx");
1454  auto prototype = view->getPrototype();
1455  if (prototype == nullptr) return;
1456  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1457  if (particleSystem == nullptr) return;
1458 
1459  //
1460  try {
1461  {
1462  auto newParticleSystemTypeId = Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_type"))->getController()->getValue().getString());
1463  auto newParticleSystemType = PrototypeParticleSystem_Type::NONE;
1464  switch (newParticleSystemTypeId) {
1465  case 1: newParticleSystemType = PrototypeParticleSystem_Type::OBJECT_PARTICLE_SYSTEM; break;
1466  case 2: newParticleSystemType = PrototypeParticleSystem_Type::POINT_PARTICLE_SYSTEM; break;
1467  case 3: newParticleSystemType = PrototypeParticleSystem_Type::FOG_PARTICLE_SYSTEM; break;
1468  default:
1469  Console::println("ParticleSystemEditorTabController::applyParticleSystemDetails: unknown particle system type");
1470  break;
1471  }
1472 
1473  // check if to change particle system emitter
1474  if (particleSystem->getType() != newParticleSystemType) {
1476  particleSystem->setType(newParticleSystemType);
1477  //
1478  setParticleSystemDetails(particleSystemIdx);
1480  return;
1481  }
1482  }
1483 
1484  //
1485  if (particleSystem->getType() == PrototypeParticleSystem_Type::OBJECT_PARTICLE_SYSTEM) {
1486  auto ops = particleSystem->getObjectParticleSystem();
1487  auto scale = Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_object_scale"))->getController()->getValue().getString());
1488  ops->setScale(Vector3(scale, scale, scale));
1489  ops->setMaxCount(Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_object_maxcount"))->getController()->getValue().getString()));
1490  ops->setAutoEmit(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_object_autoemit"))->getController()->getValue().getString() == "1");
1491  } else
1492  if (particleSystem->getType() == PrototypeParticleSystem_Type::POINT_PARTICLE_SYSTEM) {
1493  auto pps = particleSystem->getPointParticleSystem();
1494  pps->setPointSize(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_size"))->getController()->getValue().getString()));
1495  pps->setMaxPoints(Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_maxcount"))->getController()->getValue().getString()));
1496  pps->setTextureHorizontalSprites(Math::max(1, Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_horizontal_sprites"))->getController()->getValue().getString())));
1497  pps->setTextureVerticalSprites(Math::max(1, Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_vertical_sprites"))->getController()->getValue().getString())));
1498  pps->setTextureSpritesFPS(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_fps"))->getController()->getValue().getString()));
1499  pps->setAutoEmit(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_point_autoemit"))->getController()->getValue().getString() == "1");
1500  } else
1501  if (particleSystem->getType() == PrototypeParticleSystem_Type::FOG_PARTICLE_SYSTEM) {
1502  auto fps = particleSystem->getFogParticleSystem();
1503  fps->setPointSize(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_size"))->getController()->getValue().getString()));
1504  fps->setMaxPoints(Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_maxcount"))->getController()->getValue().getString()));
1505  fps->setTextureHorizontalSprites(Math::max(1, Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_horizontal_sprites"))->getController()->getValue().getString())));
1506  fps->setTextureVerticalSprites(Math::max(1, Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_vertical_sprites"))->getController()->getValue().getString())));
1507  fps->setTextureSpritesFPS(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particletype_fog_fps"))->getController()->getValue().getString()));
1508  }
1509 
1510  //
1511  auto newEmitterTypeId = Integer::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->getValue().getString());
1512  auto newEmitterType = PrototypeParticleSystem_Emitter::NONE;
1513  switch (newEmitterTypeId) {
1514  case 1: newEmitterType = PrototypeParticleSystem_Emitter::POINT_PARTICLE_EMITTER; break;
1515  case 2: newEmitterType = PrototypeParticleSystem_Emitter::BOUNDINGBOX_PARTICLE_EMITTER; break;
1516  case 3: newEmitterType = PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER; break;
1517  case 4: newEmitterType = PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER_PLANE_VELOCITY; break;
1518  case 5: newEmitterType = PrototypeParticleSystem_Emitter::SPHERE_PARTICLE_EMITTER; break;
1519  default:
1520  Console::println("ParticleSystemEditorTabController::applyParticleSystemDetails: unknown emitter");
1521  break;
1522  }
1523 
1524  // check if to change particle system emitter
1525  if (particleSystem->getEmitter() != newEmitterType) {
1527  particleSystem->setEmitter(newEmitterType);
1528  //
1529  setParticleSystemDetails(particleSystemIdx);
1531  //
1532  return;
1533  }
1534 
1535  //
1536  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("details_particletype"))->getActiveConditions().add("open");
1537 
1538  //
1539  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::POINT_PARTICLE_EMITTER) {
1540  auto ppse = particleSystem->getPointParticleEmitter();
1541  ppse->setPosition(
1542  Vector3(
1543  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_x"))->getController()->getValue().getString()),
1544  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_y"))->getController()->getValue().getString()),
1545  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_z"))->getController()->getValue().getString())
1546  )
1547  );
1548  ppse->setCount(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_count"))->getController()->getValue().getString()));
1549  ppse->setLifeTime(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_lifetime_min"))->getController()->getValue().getString()));
1550  ppse->setLifeTimeRnd(
1551  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_lifetime_max"))->getController()->getValue().getString()) -
1552  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_lifetime_min"))->getController()->getValue().getString())
1553  );
1554  ppse->setMass(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_mass_min"))->getController()->getValue().getString()));
1555  ppse->setMassRnd(
1556  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_mass_max"))->getController()->getValue().getString()) -
1557  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_mass_min"))->getController()->getValue().getString())
1558  );
1559  auto velocityMin =
1560  Vector3(
1561  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_min_x"))->getController()->getValue().getString()),
1562  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_min_y"))->getController()->getValue().getString()),
1563  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_min_z"))->getController()->getValue().getString())
1564  );
1565  auto velocityMax =
1566  Vector3(
1567  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_max_x"))->getController()->getValue().getString()),
1568  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_max_y"))->getController()->getValue().getString()),
1569  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_velocity_max_z"))->getController()->getValue().getString())
1570  );
1571  ppse->setVelocity(velocityMin);
1572  ppse->setVelocityRnd(velocityMax.clone().sub(velocityMin));
1573  } else
1574  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::BOUNDINGBOX_PARTICLE_EMITTER) {
1575  auto bbpe = particleSystem->getBoundingBoxParticleEmitters();
1576  bbpe->setObbCenter(
1577  Vector3(
1578  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_x"))->getController()->getValue().getString()),
1579  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_y"))->getController()->getValue().getString()),
1580  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_z"))->getController()->getValue().getString())
1581  )
1582  );
1583  Transform transform;
1584  transform.addRotation(OrientedBoundingBox::AABB_AXIS_Z, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_z"))->getController()->getValue().getString()));
1585  transform.addRotation(OrientedBoundingBox::AABB_AXIS_Y, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_y"))->getController()->getValue().getString()));
1586  transform.addRotation(OrientedBoundingBox::AABB_AXIS_X, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_x"))->getController()->getValue().getString()));
1587  transform.update();
1588  Vector3 obbAxis0;
1589  Vector3 obbAxis1;
1590  Vector3 obbAxis2;
1591  transform.getTransformMatrix().getAxes(obbAxis0, obbAxis1, obbAxis2);
1592  bbpe->setObbAxis0(obbAxis0);
1593  bbpe->setObbAxis1(obbAxis1);
1594  bbpe->setObbAxis2(obbAxis2);
1595  bbpe->setObbHalfextension(
1596  Vector3(
1597  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_x"))->getController()->getValue().getString()),
1598  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_y"))->getController()->getValue().getString()),
1599  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_z"))->getController()->getValue().getString())
1600  )
1601  );
1602  bbpe->setCount(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_count"))->getController()->getValue().getString()));
1603  bbpe->setLifeTime(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_lifetime_min"))->getController()->getValue().getString()));
1604  bbpe->setLifeTimeRnd(
1605  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_lifetime_max"))->getController()->getValue().getString()) -
1606  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_lifetime_min"))->getController()->getValue().getString())
1607  );
1608  bbpe->setMass(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_mass_min"))->getController()->getValue().getString()));
1609  bbpe->setMassRnd(
1610  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_mass_max"))->getController()->getValue().getString()) -
1611  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_mass_min"))->getController()->getValue().getString())
1612  );
1613  auto velocityMin =
1614  Vector3(
1615  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_min_x"))->getController()->getValue().getString()),
1616  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_min_y"))->getController()->getValue().getString()),
1617  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_min_z"))->getController()->getValue().getString())
1618  );
1619  auto velocityMax =
1620  Vector3(
1621  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_max_x"))->getController()->getValue().getString()),
1622  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_max_y"))->getController()->getValue().getString()),
1623  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_velocity_max_z"))->getController()->getValue().getString())
1624  );
1625  bbpe->setVelocity(velocityMin);
1626  bbpe->setVelocityRnd(velocityMax.clone().sub(velocityMin));
1627  } else
1628  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER) {
1629  auto cpse = particleSystem->getCircleParticleEmitter();
1630  cpse->setCenter(
1631  Vector3(
1632  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_x"))->getController()->getValue().getString()),
1633  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_y"))->getController()->getValue().getString()),
1634  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_z"))->getController()->getValue().getString())
1635  )
1636  );
1637 
1638  Transform transform;
1639  transform.addRotation(OrientedBoundingBox::AABB_AXIS_Z, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_z"))->getController()->getValue().getString()));
1640  transform.addRotation(OrientedBoundingBox::AABB_AXIS_Y, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_y"))->getController()->getValue().getString()));
1641  transform.addRotation(OrientedBoundingBox::AABB_AXIS_X, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_x"))->getController()->getValue().getString()));
1642  transform.update();
1643  Vector3 unusedAxis;
1644  Vector3 axis0;
1645  Vector3 axis1;
1646  transform.getTransformMatrix().getAxes(axis0, unusedAxis, axis1);
1647  cpse->setAxis0(axis0);
1648  cpse->setAxis1(axis1);
1649 
1650  cpse->setRadius(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_radius"))->getController()->getValue().getString()));
1651  cpse->setCount(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_count"))->getController()->getValue().getString()));
1652  cpse->setLifeTime(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_lifetime_min"))->getController()->getValue().getString()));
1653  cpse->setLifeTimeRnd(
1654  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_lifetime_max"))->getController()->getValue().getString()) -
1655  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_lifetime_min"))->getController()->getValue().getString())
1656  );
1657  cpse->setMass(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_mass_min"))->getController()->getValue().getString()));
1658  cpse->setMassRnd(
1659  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_mass_max"))->getController()->getValue().getString()) -
1660  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_mass_min"))->getController()->getValue().getString())
1661  );
1662  auto velocityMin =
1663  Vector3(
1664  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_min_x"))->getController()->getValue().getString()),
1665  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_min_y"))->getController()->getValue().getString()),
1666  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_min_z"))->getController()->getValue().getString())
1667  );
1668  auto velocityMax =
1669  Vector3(
1670  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_max_x"))->getController()->getValue().getString()),
1671  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_max_y"))->getController()->getValue().getString()),
1672  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_velocity_max_z"))->getController()->getValue().getString())
1673  );
1674  cpse->setVelocity(velocityMin);
1675  cpse->setVelocityRnd(velocityMax.clone().sub(velocityMin));
1676  } else
1677  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER_PLANE_VELOCITY) {
1678  auto cpse = particleSystem->getCircleParticleEmitterPlaneVelocity();
1679  cpse->setCenter(
1680  Vector3(
1681  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_x"))->getController()->getValue().getString()),
1682  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_y"))->getController()->getValue().getString()),
1683  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_z"))->getController()->getValue().getString())
1684  )
1685  );
1686 
1687  Transform transform;
1688  transform.addRotation(OrientedBoundingBox::AABB_AXIS_Z, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_z"))->getController()->getValue().getString()));
1689  transform.addRotation(OrientedBoundingBox::AABB_AXIS_Y, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_y"))->getController()->getValue().getString()));
1690  transform.addRotation(OrientedBoundingBox::AABB_AXIS_X, Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_x"))->getController()->getValue().getString()));
1691  transform.update();
1692  Vector3 unusedAxis;
1693  Vector3 axis0;
1694  Vector3 axis1;
1695  transform.getTransformMatrix().getAxes(axis0, unusedAxis, axis1);
1696  cpse->setAxis0(axis0);
1697  cpse->setAxis1(axis1);
1698 
1699  cpse->setRadius(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_radius"))->getController()->getValue().getString()));
1700  cpse->setCount(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_count"))->getController()->getValue().getString()));
1701  cpse->setLifeTime(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_lifetime_min"))->getController()->getValue().getString()));
1702  cpse->setLifeTimeRnd(
1703  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_lifetime_max"))->getController()->getValue().getString()) -
1704  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_lifetime_min"))->getController()->getValue().getString())
1705  );
1706  cpse->setMass(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_mass_min"))->getController()->getValue().getString()));
1707  cpse->setMassRnd(
1708  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_mass_max"))->getController()->getValue().getString()) -
1709  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_mass_min"))->getController()->getValue().getString())
1710  );
1711  cpse->setVelocity(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_velocity_min"))->getController()->getValue().getString()));
1712  cpse->setVelocityRnd(
1713  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_velocity_max"))->getController()->getValue().getString()) -
1714  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_velocity_min"))->getController()->getValue().getString())
1715  );
1716  } else
1717  if (particleSystem->getEmitter() == PrototypeParticleSystem_Emitter::SPHERE_PARTICLE_EMITTER) {
1718  auto spse = particleSystem->getSphereParticleEmitter();
1719  spse->setCenter(
1720  Vector3(
1721  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_x"))->getController()->getValue().getString()),
1722  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_y"))->getController()->getValue().getString()),
1723  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_z"))->getController()->getValue().getString())
1724  )
1725  );
1726  spse->setRadius(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_radius"))->getController()->getValue().getString()));
1727  spse->setCount(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_count"))->getController()->getValue().getString()));
1728  spse->setLifeTime(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_lifetime_min"))->getController()->getValue().getString()));
1729  spse->setLifeTimeRnd(
1730  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_lifetime_max"))->getController()->getValue().getString()) -
1731  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_lifetime_min"))->getController()->getValue().getString())
1732  );
1733  spse->setMass(Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_mass_min"))->getController()->getValue().getString()));
1734  spse->setMassRnd(
1735  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_mass_max"))->getController()->getValue().getString()) -
1736  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_mass_min"))->getController()->getValue().getString())
1737  );
1738  auto velocityMin =
1739  Vector3(
1740  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_min_x"))->getController()->getValue().getString()),
1741  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_min_y"))->getController()->getValue().getString()),
1742  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_min_z"))->getController()->getValue().getString())
1743  );
1744  auto velocityMax =
1745  Vector3(
1746  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_max_x"))->getController()->getValue().getString()),
1747  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_max_y"))->getController()->getValue().getString()),
1748  Float::parse(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_velocity_max_z"))->getController()->getValue().getString())
1749  );
1750  spse->setVelocity(velocityMin);
1751  spse->setVelocityRnd(velocityMax.clone().sub(velocityMin));
1752  } else {
1753  Console::println("ParticleSystemEditorTabController::applyParticleSystemDetails(): unknown emitter");
1754  }
1755  } catch (Exception& exception) {
1756  Console::println("ParticleSystemEditorTabController::applyParticleSystemDetails(): An error occurred: " + string(exception.what()));
1757  showInfoPopUp("Warning", string(exception.what()));
1758  }
1759  //
1761 }
1762 
1763 void ParticleSystemEditorTabController::updateDetails(const string& outlinerNode) {
1764  view->getEditorView()->setDetailsContent(string());
1765  if (StringTools::startsWith(outlinerNode, "particlesystems.") == true) {
1766  auto particleSystemIdx = Integer::parse(StringTools::substring(outlinerNode, string("particlesystems.").size(), outlinerNode.size()));
1767  setParticleSystemDetails(particleSystemIdx);
1768  }
1769  prototypePhysicsSubController->updateDetails(view->getPrototype(), outlinerNode);
1770  prototypeSoundsSubController->updateDetails(view->getPrototype(), nullptr, outlinerNode);
1771 }
1772 
1774  //
1775  try {
1776  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_x"))->getController()->setValue(MutableString(position.getX()));
1777  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_y"))->getController()->setValue(MutableString(position.getY()));
1778  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_point_location_z"))->getController()->setValue(MutableString(position.getZ()));
1779  } catch (Exception& exception) {
1780  Console::println("ParticleSystemEditorTabController::updatePointParticleSystemEmitter(): An error occurred: " + string(exception.what()));
1781  showInfoPopUp("Warning", string(exception.what()));
1782  }
1783 }
1784 
1785 void ParticleSystemEditorTabController::updateBoundingBoxParticleSystemEmitter(const Vector3& center, const Vector3& axis0, const Vector3& axis1, const Vector3& axis2, const Vector3& halfExtension) {
1786  //
1787  try {
1788  Matrix4x4 rotationMatrix;
1789  rotationMatrix.identity();
1790  rotationMatrix.setAxes(axis0, axis1, axis2);
1791  auto rotation = rotationMatrix.computeEulerAngles();
1792 
1793  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(2));
1794  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("box");
1795  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_x"))->getController()->setValue(MutableString(center.getX()));
1796  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_y"))->getController()->setValue(MutableString(center.getY()));
1797  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_location_z"))->getController()->setValue(MutableString(center.getZ()));
1798  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_x"))->getController()->setValue(MutableString(rotation.getX()));
1799  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_y"))->getController()->setValue(MutableString(rotation.getY()));
1800  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_rotation_z"))->getController()->setValue(MutableString(rotation.getZ()));
1801  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_x"))->getController()->setValue(MutableString(halfExtension.getX()));
1802  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_y"))->getController()->setValue(MutableString(halfExtension.getY()));
1803  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_box_halfsize_z"))->getController()->setValue(MutableString(halfExtension.getZ()));
1804  } catch (Exception& exception) {
1805  Console::println("ParticleSystemEditorTabController::updateBoundingBoxParticleSystemEmitter(): An error occurred: " + string(exception.what()));
1806  showInfoPopUp("Warning", string(exception.what()));
1807  }
1808 }
1809 
1810 void ParticleSystemEditorTabController::updateCircleParticleSystemEmitter(const Vector3& center, const Vector3& axis0, const Vector3& axis1, float radius) {
1811  //
1812  try {
1813  Matrix4x4 rotationMatrix;
1814  rotationMatrix.identity();
1815  rotationMatrix.setAxes(axis0, Vector3::computeCrossProduct(axis0, axis1), axis1);
1816  auto rotation = rotationMatrix.computeEulerAngles();
1817 
1818  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(3));
1819  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("circle");
1820  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_x"))->getController()->setValue(MutableString(center.getX()));
1821  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_y"))->getController()->setValue(MutableString(center.getY()));
1822  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_location_z"))->getController()->setValue(MutableString(center.getZ()));
1823  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_x"))->getController()->setValue(MutableString(rotation.getX()));
1824  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_y"))->getController()->setValue(MutableString(rotation.getY()));
1825  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_rotation_z"))->getController()->setValue(MutableString(rotation.getZ()));
1826  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_circle_radius"))->getController()->setValue(MutableString(radius));
1827  } catch (Exception& exception) {
1828  Console::println("ParticleSystemEditorTabController::updateCircleParticleSystemEmitter(): An error occurred: " + string(exception.what()));
1829  showInfoPopUp("Warning", string(exception.what()));
1830  }
1831 }
1832 
1833 void ParticleSystemEditorTabController::updateRadialParticleSystemEmitter(const Vector3& center, const Vector3& axis0, const Vector3& axis1, float radius) {
1834  //
1835  try {
1836  Matrix4x4 rotationMatrix;
1837  rotationMatrix.identity();
1838  rotationMatrix.setAxes(axis0, Vector3::computeCrossProduct(axis0, axis1), axis1);
1839  auto rotation = rotationMatrix.computeEulerAngles();
1840 
1841  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(4));
1842  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("radial");
1843  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_x"))->getController()->setValue(MutableString(center.getX()));
1844  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_y"))->getController()->setValue(MutableString(center.getY()));
1845  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_location_z"))->getController()->setValue(MutableString(center.getZ()));
1846  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_x"))->getController()->setValue(MutableString(rotation.getX()));
1847  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_y"))->getController()->setValue(MutableString(rotation.getY()));
1848  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_rotation_z"))->getController()->setValue(MutableString(rotation.getZ()));
1849  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_radial_radius"))->getController()->setValue(MutableString(radius));
1850  } catch (Exception& exception) {
1851  Console::println("ParticleSystemEditorTabController::updateRadialParticleSystemEmitter(): An error occurred: " + string(exception.what()));
1852  showInfoPopUp("Warning", string(exception.what()));
1853  }
1854 }
1855 
1857  //
1858  try {
1859  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type"))->getController()->setValue(MutableString(5));
1860  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_type_details"))->getActiveConditions().set("sphere");
1861  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_x"))->getController()->setValue(MutableString(center.getX()));
1862  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_y"))->getController()->setValue(MutableString(center.getY()));
1863  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_location_z"))->getController()->setValue(MutableString(center.getZ()));
1864  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("particleemitter_sphere_radius"))->getController()->setValue(MutableString(radius));
1865  } catch (Exception& exception) {
1866  Console::println("ParticleSystemEditorTabController::updateSphereParticleSystemEmitter(): An error occurred: " + string(exception.what()));
1867  showInfoPopUp("Warning", string(exception.what()));
1868  }
1869 }
1870 
1871 void ParticleSystemEditorTabController::setPointParticleSystemTexture(int particleSystemIdx, const string& fileName) {
1872  auto prototype = view->getPrototype();
1873  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1874  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
1875  if (pps == nullptr) return;
1877  try {
1878  pps->setTextureFileName(
1879  fileName,
1880  pps->getTransparencyTextureFileName()
1881  );
1882  } catch (Exception& exception) {
1883  Console::println("ParticleSystemEditorTabController::setPointParticleSystemTexture(): An error occurred: " + string(exception.what()));
1884  showInfoPopUp("Warning", string(exception.what()));
1885  }
1886  try {
1887  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_texture"))->setSource(pps->getTextureFileName());
1888  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_texture"))->setTooltip(pps->getTextureFileName());
1889  } catch (Exception& exception) {
1890  Console::println("ParticleSystemEditorTabController::setPointParticleSystemTexture(): An error occurred: " + string(exception.what()));
1891  showInfoPopUp("Warning", string(exception.what()));
1892  }
1894 }
1895 
1896 void ParticleSystemEditorTabController::setPointParticleSystemTransparencyTexture(int particleSystemIdx, const string& fileName) {
1897  auto prototype = view->getPrototype();
1898  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1899  auto pps = particleSystem != nullptr?particleSystem->getPointParticleSystem():nullptr;
1900  if (pps == nullptr) return;
1902  try {
1903  pps->setTextureFileName(
1904  pps->getTextureFileName(),
1905  fileName
1906  );
1907  } catch (Exception& exception) {
1908  Console::println("ParticleSystemEditorTabController::setPointParticleSystemTransparencyTexture(): An error occurred: " + string(exception.what()));
1909  showInfoPopUp("Warning", string(exception.what()));
1910  }
1911  try {
1912  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_transparency"))->setSource(pps->getTransparencyTextureFileName());
1913  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_point_transparency"))->setTooltip(pps->getTransparencyTextureFileName());
1914  } catch (Exception& exception) {
1915  Console::println("ParticleSystemEditorTabController::setPointParticleSystemTransparencyTexture(): An error occurred: " + string(exception.what()));
1916  showInfoPopUp("Warning", string(exception.what()));
1917  }
1919 }
1920 
1921 void ParticleSystemEditorTabController::setFogParticleSystemTexture(int particleSystemIdx, const string& fileName) {
1922  auto prototype = view->getPrototype();
1923  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1924  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1925  if (fps == nullptr) return;
1927  try {
1928  fps->setTextureFileName(
1929  fileName,
1930  fps->getTransparencyTextureFileName()
1931  );
1932  } catch (Exception& exception) {
1933  Console::println("ParticleSystemEditorTabController::setFogParticleSystemTexture(): An error occurred: " + string(exception.what()));
1934  showInfoPopUp("Warning", string(exception.what()));
1935  }
1936  try {
1937  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_texture"))->setSource(fps->getTextureFileName());
1938  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_texture"))->setTooltip(fps->getTextureFileName());
1939  } catch (Exception& exception) {
1940  Console::println("ParticleSystemEditorTabController::setFogParticleSystemTexture(): An error occurred: " + string(exception.what()));
1941  showInfoPopUp("Warning", string(exception.what()));
1942  }
1944 }
1945 
1946 void ParticleSystemEditorTabController::setFogParticleSystemTransparencyTexture(int particleSystemIdx, const string& fileName) {
1947  auto prototype = view->getPrototype();
1948  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1949  auto fps = particleSystem != nullptr?particleSystem->getFogParticleSystem():nullptr;
1950  if (fps == nullptr) return;
1952  try {
1953  fps->setTextureFileName(
1954  fps->getTextureFileName(),
1955  fileName
1956  );
1957  } catch (Exception& exception) {
1958  Console::println("ParticleSystemEditorTabController::setFogParticleSystemTransparencyTexture(): An error occurred: " + string(exception.what()));
1959  showInfoPopUp("Warning", string(exception.what()));
1960  }
1961  try {
1962  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_transparency"))->setSource(fps->getTransparencyTextureFileName());
1963  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_fog_transparency"))->setTooltip(fps->getTransparencyTextureFileName());
1964  } catch (Exception& exception) {
1965  Console::println("ParticleSystemEditorTabController::setFogParticleSystemTransparencyTexture(): An error occurred: " + string(exception.what()));
1966  showInfoPopUp("Warning", string(exception.what()));
1967  }
1969 }
1970 
1971 void ParticleSystemEditorTabController::setObjectParticleSystemModel(int particleSystemIdx, const string& fileName) {
1972  auto prototype = view->getPrototype();
1973  auto particleSystem = prototype->getParticleSystemAt(particleSystemIdx);
1974  auto ops = particleSystem != nullptr?particleSystem->getObjectParticleSystem():nullptr;
1975  if (ops == nullptr) return;
1977  try {
1978  ops->setModelFile(fileName);
1979  } catch (Exception& exception) {
1980  Console::println("ParticleSystemEditorTabController::setObjectParticleSystemModel(): An error occurred: " + string(exception.what()));
1981  showInfoPopUp("Warning", string(exception.what()));
1982  }
1983  try {
1984  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_object"))->setSource(ops->getModelFileName());
1985  required_dynamic_cast<GUIImageNode*>(screenNode->getNodeById("particletype_object"))->setTooltip(ops->getModelFileName());
1986  } catch (Exception& exception) {
1987  Console::println("ParticleSystemEditorTabController::setObjectParticleSystemModel(): An error occurred: " + string(exception.what()));
1988  showInfoPopUp("Warning", string(exception.what()));
1989  }
1991 }
Color 4 definition class.
Definition: Color4.h:18
Engine main class.
Definition: Engine.h:131
Rotation representation.
Definition: Rotation.h:18
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
virtual void update()
Computes transform matrix.
Definition: Transform.cpp:33
void addRotation(const Vector3 &axis, const float angle)
Add rotation.
Definition: Transform.h:113
const Matrix4x4 & getTransformMatrix() const
Definition: Transform.h:169
Oriented bounding box physics primitive.
PrototypeParticleSystem_PointParticleSystem * getPointParticleSystem()
PrototypeParticleSystem_ObjectParticleSystem * getObjectParticleSystem()
PrototypeParticleSystem_FogParticleSystem * getFogParticleSystem()
Prototype definition.
Definition: Prototype.h:55
void addParticleSystem(PrototypeParticleSystem *particleSystem)
Add particle system.
Definition: Prototype.h:398
PrototypeParticleSystem * getParticleSystemAt(int idx)
Get particle system at given index.
Definition: Prototype.h:389
GUI parser.
Definition: GUIParser.h:40
virtual const MutableString & getValue()=0
GUI node base class.
Definition: GUINode.h:64
const string & getToolTip()
Definition: GUINode.h:346
GUINodeController * getController()
Definition: GUINode.h:661
const string & getId()
Definition: GUINode.h:339
GUI screen node that represents a screen that can be rendered via GUI system.
Definition: GUIScreenNode.h:72
GUINode * getNodeById(const string &nodeId)
Get GUI node by id.
Standard math functions.
Definition: Math.h:19
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
Matrix4x4 & identity()
Creates identity matrix.
Definition: Matrix4x4.h:158
void getAxes(Vector3 &xAxis, Vector3 &yAxis, Vector3 &zAxis) const
Get coordinate system axes.
Definition: Matrix4x4.h:321
Vector3 computeEulerAngles() const
Compute Euler angles (rotation around x, y, z axes)
Definition: Matrix4x4.h:531
Matrix4x4 & setAxes(const Vector3 &xAxis, const Vector3 &yAxis, const Vector3 &zAxis)
Set coordinate system axes.
Definition: Matrix4x4.h:334
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
float getY() const
Definition: Vector3.h:117
float getX() const
Definition: Vector3.h:100
float getZ() const
Definition: Vector3.h:134
Vector3 & add(float scalar)
Adds a scalar.
Definition: Vector3.h:153
Vector3 clone() const
Clones this vector3.
Definition: Vector3.h:374
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Definition: Vector3.h:70
void show(const Color4 &color, Action *onColorChangeAction)
Shows the pop up.
void show(int mouseX, int mouseY)
Shows the pop up.
void addMenuItem(const string &text, const string &id, Action *action=nullptr)
Add menu item.
bool isDropOnNode(int dropX, int dropY, const string &nodeId)
Is drop on node.
void browseTo(const string &fileName)
Browse to file name.
void show(const string &cwd, const string &captionText, const vector< string > &extensions, const string &fileName, bool enableFilter, Action *applyAction, Action *cancelAction=nullptr, const string &settingsFileName=".filedialog.properties", const string &settingsPathName=string())
Shows the file dialog pop up.
void show(const string &caption, const string &message)
Shows the pop up.
void show(int mouseX, int mouseY, const string &tooltip)
Show tooltip.
Pop ups controller accessor class.
Definition: PopUps.h:29
ColorPickerScreenController * getColorPickerScreenController()
Definition: PopUps.h:89
FileDialogScreenController * getFileDialogScreenController()
Definition: PopUps.h:61
TooltipScreenController * getTooltipScreenController()
Definition: PopUps.h:131
ContextMenuScreenController * getContextMenuScreenController()
Definition: PopUps.h:96
InfoDialogScreenController * getInfoDialogScreenController()
Definition: PopUps.h:75
void onContextMenuRequest(GUIElementNode *node, int mouseX, int mouseY) override
On context menu request.
void onDrop(const string &payload, int mouseX, int mouseY) override
On drop.
void applyParticleSystemDetails(int particleSystemIdx)
Apply particle system details.
void setObjectParticleSystemModel(int particleSystemIdx, const string &fileName)
Set object particle system model.
void updateSphereParticleSystemEmitter(const Vector3 &center, float radius)
Update sphere particle system emitter.
void setFogParticleSystemTransparencyTexture(int particleSystemIdx, const string &fileName)
Set fog particle system transparency texture.
void setPointParticleSystemTransparencyTexture(int particleSystemIdx, const string &fileName)
Set point particle system transparency texture.
void setFogParticleSystemTexture(int particleSystemIdx, const string &fileName)
Set fog particle system texture.
void updateCircleParticleSystemEmitter(const Vector3 &center, const Vector3 &axis0, const Vector3 &axis1, float radius)
Update circle particle system emitter.
void setPointParticleSystemTexture(int particleSystemIdx, const string &fileName)
Set point particle system texture.
void updateRadialParticleSystemEmitter(const Vector3 &center, const Vector3 &axis0, const Vector3 &axis1, float radius)
Update radial particle system emitter.
void setParticleSystemDetails(int particleSystemIdx)
Set particle system details.
void showInfoPopUp(const string &caption, const string &message)
Show the information pop up / modal.
void onAction(GUIActionListenerType type, GUIElementNode *node) override
void updatePointParticleSystemEmitter(const Vector3 &position)
Update point particle system emitter.
void updateBoundingBoxParticleSystemEmitter(const Vector3 &center, const Vector3 &axis0, const Vector3 &axis1, const Vector3 &axis2, const Vector3 &halfExtension)
Update bounding box particle system emitter.
void onTooltipShowRequest(GUINode *node, int mouseX, int mouseY) override
On tooltip show request.
void saveFile(const string &pathName, const string &fileName)
Saving prototype as tempty prototype.
void setParticleSystemIndex(int idx, bool changeOutlinerSelection=true)
Set particle system index, the particle system to edit.
void setOutlinerAddDropDownContent(const string &xml)
Set outliner add drop down content.
Definition: EditorView.cpp:400
void setOutlinerContent(const string &xml)
Set outliner content.
Definition: EditorView.cpp:396
EditorScreenController * getScreenController()
Definition: EditorView.h:69
void setDetailsContent(const string &xml)
Set details content.
Definition: EditorView.cpp:404
bool getCurrentTabTooltipPosition(GUIScreenNode *screenNode, int mouseX, int mouseY, int &tooltipLeft, int &tooltipTop)
Determine current tab tooltip position.
Definition: EditorView.cpp:439
void reloadTabOutliner(const string &newSelectionValue=string())
Reload tab outliner.
Definition: EditorView.cpp:408
Console class.
Definition: Console.h:29
Exception base class.
Definition: ExceptionBase.h:19
Float class.
Definition: Float.h:27
Integer class.
Definition: Integer.h:25
Mutable utf8 aware string class.
Definition: MutableString.h:23
const string & getString() const
String tools class.
Definition: StringTools.h:22
std::exception Exception
Exception base class.
Definition: Exception.h:18
Tab controller, which connects UI with logic.
Definition: TabController.h:34
Action Interface.
Definition: Action.h:11