Benchmark03_MoleculeLogic.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "Benchmark03_MoleculeLogic.h"
  4. #include <Urho3D/Scene/Scene.h>
  5. #include <Urho3D/DebugNew.h>
  6. using namespace Urho3D;
  7. Benchmark03_MoleculeLogic::Benchmark03_MoleculeLogic(Context* context)
  8. : LogicComponent(context)
  9. , moleculeType_(0)
  10. {
  11. SetUpdateEventMask(LogicComponentEvents::Update | LogicComponentEvents::PostUpdate);
  12. }
  13. void Benchmark03_MoleculeLogic::SetParameters(i32 type)
  14. {
  15. moleculeType_ = type;
  16. }
  17. static constexpr float MOLECULE_RADIUS = 1.f;
  18. static constexpr float INTERACTION_RANGE = MOLECULE_RADIUS * 4.f;
  19. static constexpr float CONTAINER_RADIUS = 9.f;
  20. void Benchmark03_MoleculeLogic::Update(float timeStep)
  21. {
  22. Vector<Node*> moleculeNodes;
  23. GetScene()->GetChildrenWithComponent<Benchmark03_MoleculeLogic>(moleculeNodes);
  24. Vector2 moleculePos = node_->GetPosition2D();
  25. for (Node* anotherMoleculeNode : moleculeNodes)
  26. {
  27. if (anotherMoleculeNode == node_)
  28. continue;
  29. Vector2 anotherMoleculePos = anotherMoleculeNode->GetPosition2D();
  30. i32 anotherMoleculeType = anotherMoleculeNode->GetComponent<Benchmark03_MoleculeLogic>()->GetMoleculeType();
  31. float distance = (anotherMoleculePos - moleculePos).Length();
  32. if (Equals(distance, 0.f))
  33. {
  34. // Molecules are at the same point
  35. velocity_ = Vector2(Random(-2.f, 2.f), Random(-2.f, 2.f));
  36. continue;
  37. }
  38. // Molecules are too far away and don't interact
  39. if (distance >= INTERACTION_RANGE)
  40. continue;
  41. Vector2 direction = (anotherMoleculePos - moleculePos).Normalized();
  42. float forceModulus = 1.f - distance / INTERACTION_RANGE;
  43. forceModulus = forceModulus * forceModulus * forceModulus;
  44. forceModulus = forceModulus * 25.f;
  45. if (moleculeType_ != anotherMoleculeType)
  46. forceModulus *= 1.5f;
  47. force_ -= forceModulus * direction;
  48. }
  49. if (moleculePos.Length() > CONTAINER_RADIUS - MOLECULE_RADIUS)
  50. {
  51. Vector2 backDirection = -moleculePos.Normalized();
  52. float backModulus = (moleculePos.Length() - CONTAINER_RADIUS + MOLECULE_RADIUS) * 50.0f;
  53. force_ = force_ + backDirection * backModulus;
  54. }
  55. velocity_ = velocity_ + force_ * timeStep;
  56. velocity_ = velocity_.Lerp(Vector2::ZERO, timeStep * 0.5f);
  57. }
  58. void Benchmark03_MoleculeLogic::PostUpdate(float timeStep)
  59. {
  60. node_->Translate2D(velocity_ * timeStep);
  61. force_ = Vector2::ZERO;
  62. }