Curl.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #pragma once
  2. #include "vmath.hpp" // PORTME: vmath can be replaced with IG's internal math equivalents
  3. #define USING_UNITY 0
  4. #if USING_UNITY
  5. #define DLLEXPORT __declspec(dllexport)
  6. #else
  7. #define DLLEXPORT
  8. #endif
  9. namespace CurlNoise
  10. {
  11. using namespace Vectormath::Aos;
  12. // This class encapsulates different volume collider primitives for the purpose of distance field estimation
  13. // It does NOT handle irregular scaling for curved primitives (for ex, ellipsoids, ellipsoid cylinders..) at the moment.
  14. // PORTME: IG Core already defines different Volume types. It seems to have a distance field function GetSignedDistancePoint(..)
  15. // It handles all the primitive shapes defined below, but approximates some of them
  16. // (for ex, box distance is Manhattan distance to the corner point)
  17. // I'd guess that being tied to SceneObject, that would end up being shared with the vfx system.
  18. // This is just a place holder for proof of concept and testing.
  19. class Volume
  20. {
  21. enum eShape
  22. {
  23. kSphere,
  24. kCylinder,
  25. kBox,
  26. kCount
  27. };
  28. public:
  29. // constructor overloads for various primitive types
  30. Volume(const Matrix4& worldToObjectNoScale, float r); // sphere
  31. Volume(const Matrix4& worldToObjectNoScale, const Vector3& extents); // box
  32. Volume(const Matrix4& worldToObjectNoScale, float r, float h); // cylinder
  33. float DistanceToSurface(const Vector3& wsPos) const;
  34. inline void SetWorldToObjectTransform(const Matrix4& m);
  35. inline Vector3 GetWorldPos() const;
  36. protected:
  37. eShape m_Shape;
  38. Vector3 m_Extents; // world space units; interpreted based on the shape
  39. Matrix4 m_WorldToObject; // inverse of the object to world matrix consisting of only translation and rotation
  40. };
  41. struct CurlSettings
  42. {
  43. // true => the gradient is calculated as vector from center of nearest collider to the particle
  44. // false => the gradient is calculated based on the change of the distance field wrt xyz
  45. bool m_bCheapGradient = true;
  46. //--- See PerlinNoise3::Noise for how the following fields are used ---
  47. // base frequency to control how often the noise changes per world-space unit
  48. float m_Frequency = 1.f;
  49. // number of octaves to sum up. each successive octave scales the previous octave's frequency by the lacunarity
  50. unsigned int m_NumOctaves = 2;
  51. // factor by which frequency changes in successive octaves
  52. float m_Lacunarity = 2.0f;
  53. // factor by which amplitude changes in successive octaves
  54. float m_Persistence = 0.5f;
  55. };
  56. #if USING_UNITY
  57. extern "C"
  58. {
  59. struct float3
  60. {
  61. float val[3];
  62. };
  63. DLLEXPORT float3 ComputeCurlBruteForce(Vector3 wsPos, Volume *pColliders, unsigned int length);
  64. DLLEXPORT float3 ComputeCurlNoBoundaries(Vector3 wsPos);
  65. DLLEXPORT float3 ComputeCurlNonBruteForce(Vector3 wsPos, Volume *pColliders, unsigned int length);
  66. DLLEXPORT void SetCurlSettings( bool bCheapGradient,
  67. float frequency,
  68. unsigned int numOctaves,
  69. float lacunarity,
  70. float persistence);
  71. }
  72. #else
  73. // API for visual effect system to use
  74. Vector3 ComputeCurl(Vector3 wsPos, const Volume *pColliders, unsigned int length);
  75. Vector3 ComputeCurlWithoutObstacles(Vector3 wsPos);
  76. void SetCurlSettings(const CurlSettings& settings);
  77. #endif
  78. };