ExternalForcesModule.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // ExternalForcesModule.cpp
  3. // libcocos2d Mac
  4. //
  5. // Created by 徐俊杰 on 2020/4/24.
  6. //
  7. #include "rparticle/Modules/ExternalForcesModule.h"
  8. //#include "UnityPrefix.h"
  9. //#include "rparticle/Modules/ExternalForcesModule.h"
  10. //#include "Runtime/BaseClasses/ObjectDefines.h"
  11. #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h"
  12. #include "rparticle/ParticleSystemUtils.h"
  13. #include "rparticle/Utilities/Transform.h"
  14. //#include "Runtime/Geometry/Intersection.h"
  15. //#include "Runtime/Geometry/Sphere.h"
  16. //#include "Runtime/Terrain/Wind.h"
  17. //#include "Runtime/Input/TimeManager.h"
  18. NS_RRP_BEGIN
  19. void ApplyRadialForce(ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, const Vector3f position, const float radius, const float force, const float dt)
  20. {
  21. for(int q = fromIndex; q < toIndex; q++)
  22. {
  23. Vector3f toForce = position - ps.position[q];
  24. float distanceToForce = Magnitude(toForce);
  25. toForce = NormalizeSafe(toForce);
  26. float forceFactor = clamp(distanceToForce/radius, 0.0f, 1.0f);
  27. forceFactor = 1.0f - forceFactor * forceFactor;
  28. Vector3f delta = toForce * force * forceFactor * dt;
  29. ps.velocity[q] += delta;
  30. }
  31. }
  32. void ApplyDirectionalForce(ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, const Vector3f position, const Vector3f direction, const float radius, const float force, const float dt)
  33. {
  34. for(int q = fromIndex; q < toIndex; q++)
  35. {
  36. Vector3f delta = direction * force * dt;
  37. ps.velocity[q] += delta;
  38. }
  39. }
  40. ExternalForcesModule::ExternalForcesModule () : ParticleSystemModule(false)
  41. , m_Multiplier (1.0f)
  42. {
  43. }
  44. void ExternalForcesModule::Update (const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, float dt)
  45. {
  46. Matrix4x4f matrix = Matrix4x4f::IDENTITY;
  47. if(roState.useLocalSpace)
  48. Matrix4x4f::Invert_General3D(state.localToWorld, matrix);
  49. auto aabb = state.minMaxAABB;
  50. for(int i = 0; i < state.numCachedForces; i++)
  51. {
  52. const ParticleSystemExternalCachedForce& cachedForce = state.cachedForces[i];
  53. const Vector3f position = matrix.MultiplyPoint3(cachedForce.position);
  54. const Vector3f direction = matrix.MultiplyVector3(cachedForce.direction);
  55. const float radius = cachedForce.radius;
  56. const float force = cachedForce.forceMain * m_Multiplier;
  57. //TODO: WindZone
  58. /*
  59. const WindZone::WindZoneMode forceType = (WindZone::WindZoneMode)cachedForce.forceType;
  60. if(WindZone::Spherical == forceType)
  61. {
  62. Sphere sphere (position, radius);
  63. if(!IntersectAABBSphere (aabb, sphere))
  64. continue;
  65. ApplyRadialForce(ps, fromIndex, toIndex, position, radius, force, dt);
  66. }
  67. else if(WindZone::Directional == forceType)
  68. ApplyDirectionalForce(ps, fromIndex, toIndex, position, direction, radius, force, dt);
  69. */
  70. }
  71. }
  72. // TODO: Perform culling here, instead of caching all of them
  73. void ExternalForcesModule::AllocateAndCache(const ParticleSystemReadOnlyState& roState, ParticleSystemState& state)
  74. {
  75. //TODO: WindManager, TimeManager
  76. /*
  77. float time = GetTimeManager ().GetTimeSinceLevelLoad ();
  78. WindManager::WindZoneList& windZones = WindManager::GetInstance().GetList();
  79. state.numCachedForces = 0;
  80. for (WindManager::WindZoneList::iterator it = windZones.begin (); it != windZones.end (); ++it)
  81. state.numCachedForces++;
  82. // Allocate
  83. state.cachedForces = ALLOC_TEMP_MANUAL(ParticleSystemExternalCachedForce, state.numCachedForces);
  84. // Cache
  85. int i = 0;
  86. for (WindManager::WindZoneList::iterator it = windZones.begin (); it != windZones.end (); ++it)
  87. {
  88. const WindZone& zone = **it;
  89. ParticleSystemExternalCachedForce& cachedForce = state.cachedForces[i++];
  90. cachedForce.position = zone.GetComponent (Transform).GetPosition();
  91. cachedForce.direction = zone.GetComponent (Transform).GetLocalToWorldMatrix().GetAxisZ();
  92. cachedForce.forceType = zone.GetMode();
  93. cachedForce.radius = zone.GetRadius();
  94. float phase = time * kPI * zone.GetWindPulseFrequency();
  95. float pulse = (cos (phase) + cos (phase * 0.375f) + cos (phase * 0.05f)) * 0.333f;
  96. pulse = 1.0f + (pulse * zone.GetWindPulseMagnitude());
  97. cachedForce.forceMain = zone.GetWindMain() * pulse;
  98. // Maybe implement using turbulence and time based phasing?
  99. // ForceTurbulenceMultiply (maybe) // @TODO: Figure out what to do about turbulence. Do perlin field? Expensive but maybe cool! If use it: only do it when turbulence force is set to something
  100. //cachedForce.force = 1.0f;
  101. }
  102. */
  103. }
  104. void ExternalForcesModule::FreeCache(ParticleSystemState& state)
  105. {
  106. if(state.cachedForces)
  107. FREE_TEMP_MANUAL(state.cachedForces);
  108. state.cachedForces = NULL;
  109. state.numCachedForces = 0;
  110. }
  111. template<class TransferFunction>
  112. void ExternalForcesModule::Transfer (TransferFunction& transfer)
  113. {
  114. ParticleSystemModule::Transfer (transfer);
  115. transfer.Transfer (m_Multiplier, "multiplier");
  116. }
  117. INSTANTIATE_TEMPLATE_TRANSFER(ExternalForcesModule)
  118. NS_RRP_END