18 #ifndef B2_PARTICLE_SYSTEM_H
19 #define B2_PARTICLE_SYSTEM_H
21 #include <Box2D/Common/b2SlabAllocator.h>
23 #include <Box2D/Dynamics/b2TimeStep.h>
25 #ifdef LIQUIDFUN_UNIT_TESTS
26 #include <gtest/gtest.h>
27 #endif // LIQUIDFUN_UNIT_TESTS
43 class b2ParticlePairSet;
227 const bool callDestructionListener);
255 bool callDestructionListener);
403 void SetPositionBuffer(
b2Vec2* buffer, int32 capacity);
404 void SetVelocityBuffer(
b2Vec2* buffer, int32 capacity);
406 void SetUserDataBuffer(
void** buffer, int32 capacity);
412 int32 GetContactCount();
418 int32 GetBodyContactCount();
549 const b2Vec2& point2)
const;
559 friend class b2ParticleBodyContactRemovePredicate;
560 #ifdef LIQUIDFUN_UNIT_TESTS
561 FRIEND_TEST(FunctionTests, GetParticleMass);
562 #endif // LIQUIDFUN_UNIT_TESTS
564 template <
typename T>
565 struct UserOverridableBuffer
567 UserOverridableBuffer()
570 userSuppliedCapacity = 0;
573 int32 userSuppliedCapacity;
581 friend inline bool operator<(
const Proxy &a,
const Proxy &b)
583 return a.tag < b.tag;
585 friend inline bool operator<(uint32 a,
const Proxy &b)
589 friend inline bool operator<(
const Proxy &a, uint32 b)
598 int32 indexA, indexB;
607 int32 indexA, indexB, indexC;
611 float32 ka, kb, kc, s;
615 class ConnectionFilter
618 virtual ~ConnectionFilter() {}
621 virtual bool IsNecessary(int32 index)
const
627 virtual bool ShouldCreatePair(int32 a, int32 b)
const
634 virtual bool ShouldCreateTriad(int32 a, int32 b, int32 c)
const
644 static const int32 k_pairFlags =
648 static const int32 k_triadFlags =
651 static const int32 k_noPressureFlags =
655 static const int32 k_extraDampingFlags =
661 template <
typename T>
void FreeBuffer(T** b,
int capacity);
662 template <
typename T>
void FreeUserOverridableBuffer(
663 UserOverridableBuffer<T>* b);
664 template <
typename T> T* ReallocateBuffer(T* buffer, int32 oldCapacity,
666 template <
typename T> T* ReallocateBuffer(
667 T* buffer, int32 userSuppliedCapacity, int32 oldCapacity,
668 int32 newCapacity,
bool deferred);
669 template <
typename T> T* ReallocateBuffer(
670 UserOverridableBuffer<T>* buffer, int32 oldCapacity, int32 newCapacity,
672 template <
typename T> T* RequestBuffer(T* buffer);
673 template <
typename T> T* RequestGrowableBuffer(T* buffer,
674 int32 count, int32 *capacity);
678 void ReallocateHandleBuffers(int32 newCapacity);
680 void ReallocateInternalAllocatedBuffers(int32 capacity);
681 int32 CreateParticleForGroup(
684 void CreateParticlesStrokeShapeForGroup(
687 void CreateParticlesFillShapeForGroup(
690 void CreateParticlesWithShapeForGroup(
693 void CreateParticlesWithShapesForGroup(
694 const b2Shape*
const* shapes, int32 shapeCount,
698 void UpdatePairsAndTriads(
699 int32 firstIndex, int32 lastIndex,
const ConnectionFilter& filter);
700 void UpdatePairsAndTriadsWithReactiveParticles();
701 static bool ComparePairIndices(
const Pair& a,
const Pair& b);
702 static bool MatchPairIndices(
const Pair& a,
const Pair& b);
703 static bool CompareTriadIndices(
const Triad& a,
const Triad& b);
704 static bool MatchTriadIndices(
const Triad& a,
const Triad& b);
707 void UpdateAllParticleFlags();
708 void UpdateAllGroupFlags();
709 void AddContact(int32 a, int32 b,
b2ContactFilter*
const contactFilter,
711 b2ParticlePairSet*
const particlePairSet);
712 void UpdateContacts(
bool exceptZombie);
713 void UpdateBodyContacts();
720 void SolveStaticPressure(
const b2TimeStep& step);
721 void ComputeWeight();
724 void SolveExtraDamping();
735 void SolveColorMixing();
740 void RotateBuffer(int32 start, int32 mid, int32 end);
742 float32 GetCriticalVelocity(
const b2TimeStep& step)
const;
743 float32 GetCriticalVelocitySquared(
const b2TimeStep& step)
const;
744 float32 GetCriticalPressure(
const b2TimeStep& step)
const;
745 float32 GetParticleStride()
const;
746 float32 GetParticleMass()
const;
747 float32 GetParticleInvMass()
const;
765 template <
typename T>
void SetUserOverridableBuffer(
766 UserOverridableBuffer<T>* buffer, T* newBufferData, int32 newCapacity);
770 void RemoveSpuriousBodyContacts();
774 void DetectStuckParticle(int32 particle);
777 bool ValidateParticleIndex(
const int32 index)
const;
780 int32 GetQuantizedTimeElapsed()
const;
782 int64 LifetimeToExpirationTime(
const float32 lifetime)
const;
784 bool ForceCanBeApplied(uint32 flags)
const;
785 void PrepareForceBuffer();
789 int32 m_allParticleFlags;
790 bool m_needsUpdateAllParticleFlags;
791 int32 m_allGroupFlags;
792 bool m_needsUpdateAllGroupFlags;
794 int32 m_iterationIndex;
796 float32 m_inverseDensity;
797 float32 m_gravityScale;
798 float32 m_particleDiameter;
799 float32 m_inverseDiameter;
800 float32 m_squaredDiameter;
801 bool m_strictContactCheck;
804 int32 m_internalAllocatedCapacity;
809 UserOverridableBuffer<b2ParticleHandle*> m_handleIndexBuffer;
810 UserOverridableBuffer<uint32> m_flagsBuffer;
811 UserOverridableBuffer<b2Vec2> m_positionBuffer;
812 UserOverridableBuffer<b2Vec2> m_velocityBuffer;
816 float32* m_weightBuffer;
821 float32* m_staticPressureBuffer;
824 float32* m_accumulationBuffer;
829 b2Vec2* m_accumulation2Buffer;
834 float32* m_depthBuffer;
835 UserOverridableBuffer<b2ParticleColor> m_colorBuffer;
837 UserOverridableBuffer<void*> m_userDataBuffer;
840 int32 m_stuckThreshold;
841 UserOverridableBuffer<int32> m_lastBodyContactStepBuffer;
842 UserOverridableBuffer<int32> m_bodyContactCountBuffer;
843 UserOverridableBuffer<int32> m_consecutiveContactStepsBuffer;
844 int32 m_stuckParticleCount;
845 int32 m_stuckParticleCapacity;
846 int32 *m_stuckParticleBuffer;
849 int32 m_proxyCapacity;
850 Proxy* m_proxyBuffer;
852 int32 m_contactCount;
853 int32 m_contactCapacity;
856 int32 m_bodyContactCount;
857 int32 m_bodyContactCapacity;
861 int32 m_pairCapacity;
865 int32 m_triadCapacity;
866 Triad* m_triadBuffer;
871 UserOverridableBuffer<int32> m_expirationTimeBuffer;
873 UserOverridableBuffer<int32> m_indexByExpirationTimeBuffer;
879 bool m_expirationTimeBufferRequiresSorting;
923 return m_contactBuffer;
926 inline int32 b2ParticleSystem::GetContactCount()
928 return m_contactCount;
933 return m_bodyContactBuffer;
936 inline int32 b2ParticleSystem::GetBodyContactCount()
938 return m_bodyContactCount;
953 return m_stuckParticleBuffer;
958 return m_stuckParticleCount;
963 m_strictContactCheck = enabled;
968 return m_strictContactCheck;
973 m_particleDiameter = 2 * radius;
974 m_squaredDiameter = m_particleDiameter * m_particleDiameter;
975 m_inverseDiameter = 1 / m_particleDiameter;
981 m_inverseDensity = 1 / m_density;
991 m_gravityScale = gravityScale;
996 return m_gravityScale;
1021 return m_particleDiameter / 2;
1024 inline float32 b2ParticleSystem::GetCriticalVelocity(
const b2TimeStep& step)
const
1026 return m_particleDiameter * step.inv_dt;
1029 inline float32 b2ParticleSystem::GetCriticalVelocitySquared(
1032 float32 velocity = GetCriticalVelocity(step);
1033 return velocity * velocity;
1036 inline float32 b2ParticleSystem::GetCriticalPressure(
const b2TimeStep& step)
const
1038 return m_density * GetCriticalVelocitySquared(step);
1041 inline float32 b2ParticleSystem::GetParticleStride()
const
1046 inline float32 b2ParticleSystem::GetParticleMass()
const
1048 float32 stride = GetParticleStride();
1049 return m_density * stride * stride;
1052 inline float32 b2ParticleSystem::GetParticleInvMass()
const
1056 return m_inverseDensity * inverseStride * inverseStride;
1061 return m_positionBuffer.data;
1066 return m_velocityBuffer.data;
1076 b2Assert(m_count <= count);
1082 return m_flagsBuffer.data;
1087 return m_positionBuffer.data;
1092 return m_velocityBuffer.data;
1102 return m_groupBuffer;
1112 return m_groupBuffer;
1120 inline bool b2ParticleSystem::ValidateParticleIndex(
const int32 index)
const
const int32 * GetExpirationTimeBuffer()
Definition: b2ParticleSystem.cpp:3527
float32 ExpirationTimeToLifetime(const int32 expirationTime) const
Definition: b2ParticleSystem.cpp:3509
Prevents other particles from leaking.
Definition: b2Particle.h:54
void SetPaused(bool paused)
Definition: b2ParticleSystem.h:911
float32 radius
Particles behave as circles with this radius. In Box2D units.
Definition: b2ParticleSystem.h:111
void ApplyForce(int32 firstIndex, int32 lastIndex, const b2Vec2 &force)
Definition: b2ParticleSystem.cpp:3687
const uint32 * GetFlagsBuffer() const
Definition: b2ParticleSystem.h:1080
b2Vec2 * GetVelocityBuffer()
Definition: b2ParticleSystem.h:1064
Definition: b2ParticleSystem.h:84
const b2ParticleBodyContact * GetBodyContacts()
Definition: b2ParticleSystem.h:931
void ParticleApplyLinearImpulse(int32 index, const b2Vec2 &impulse)
Definition: b2ParticleSystem.h:1131
float32 repulsiveStrength
Definition: b2ParticleSystem.h:146
float32 GetRadius() const
Get the particle radius.
Definition: b2ParticleSystem.h:1019
float32 lifetimeGranularity
Definition: b2ParticleSystem.h:186
void SetDensity(float32 density)
Definition: b2ParticleSystem.h:978
const b2ParticleHandle * GetParticleHandleFromIndex(const int32 index)
Retrieve a handle to the particle at the specified index.
Definition: b2ParticleSystem.cpp:739
Definition: b2ParticleGroup.h:51
uint32 flags
Definition: b2ParticleSystem.h:52
float32 ComputeCollisionEnergy() const
Compute the kinetic energy that can be lost by damping force.
Definition: b2ParticleSystem.cpp:3842
float32 weight
Definition: b2ParticleSystem.h:57
Definition: b2WorldCallbacks.h:241
b2ParticleColor * GetColorBuffer()
Definition: b2ParticleSystem.cpp:548
void RayCast(b2RayCastCallback *callback, const b2Vec2 &point1, const b2Vec2 &point2) const
Definition: b2ParticleSystem.cpp:3780
void SetParticleLifetime(const int32 index, const float32 lifetime)
Definition: b2ParticleSystem.cpp:3473
b2ParticleGroup * GetParticleGroupList()
Definition: b2ParticleSystem.h:891
float32 weight
Weight of the contact. A value between 0.0f and 1.0f.
Definition: b2ParticleSystem.h:75
Definition: b2StackAllocator.h:37
b2Vec2 normal
The normalized direction from A to B.
Definition: b2ParticleSystem.h:60
Definition: b2ParticleSystem.h:189
int32 staticPressureIterations
Definition: b2ParticleSystem.h:168
const b2ParticleContact * GetContacts()
Definition: b2ParticleSystem.h:921
b2ParticleGroup * CreateParticleGroup(const b2ParticleGroupDef &def)
Definition: b2ParticleSystem.cpp:1034
int32 GetStuckCandidateCount() const
Get the number of stuck particle candidates from the last step.
Definition: b2ParticleSystem.h:956
void ComputeAABB(b2AABB *const aabb) const
Definition: b2ParticleSystem.cpp:1719
uint32 GetParticleFlags(const int32 index)
Get flags for a particle. See the b2ParticleFlag enum.
Definition: b2ParticleSystem.h:1115
Definition: b2BlockAllocator.h:36
float32 GetParticleLifetime(const int32 index)
Definition: b2ParticleSystem.cpp:3519
void QueryShapeAABB(b2QueryCallback *callback, const b2Shape &shape, const b2Transform &xf) const
Definition: b2ParticleSystem.cpp:3771
With restitution from deformation.
Definition: b2Particle.h:42
bool GetStrictContactCheck() const
Get the status of the strict contact check.
Definition: b2ParticleSystem.h:966
float32 colorMixingStrength
Definition: b2ParticleSystem.h:173
float32 powderStrength
Definition: b2ParticleSystem.h:150
bool GetDestructionByAge() const
Definition: b2ParticleSystem.h:1126
int32 index
Index of the particle making contact.
Definition: b2ParticleSystem.h:66
void SetMaxParticleCount(int32 count)
Definition: b2ParticleSystem.h:1074
void ParticleApplyForce(int32 index, const b2Vec2 &force)
Definition: b2ParticleSystem.cpp:3715
float32 staticPressureRelaxation
Definition: b2ParticleSystem.h:164
Definition: b2Particle.h:272
b2Vec2 normal
The normalized direction from the particle to the body.
Definition: b2ParticleSystem.h:78
Small color object for each particle.
Definition: b2Particle.h:81
Without isotropic pressure.
Definition: b2Particle.h:46
void SetParticleFlags(int32 index, uint32 flags)
Set flags for a particle. See the b2ParticleFlag enum.
Definition: b2ParticleSystem.cpp:3617
float32 pressureStrength
Definition: b2ParticleSystem.h:115
float32 ejectionStrength
Definition: b2ParticleSystem.h:154
b2Fixture * fixture
The specific fixture making contact.
Definition: b2ParticleSystem.h:72
float32 mass
The effective mass used in calculating force.
Definition: b2ParticleSystem.h:81
const int32 * GetStuckCandidates() const
Definition: b2ParticleSystem.h:951
void SetDamping(float32 damping)
Definition: b2ParticleSystem.h:999
int32 GetParticleCount() const
Get the number of particles.
Definition: b2ParticleSystem.h:906
void ** GetUserDataBuffer()
Definition: b2ParticleSystem.cpp:554
With surface tension.
Definition: b2Particle.h:48
A group of particles. b2ParticleGroup::CreateParticleGroup creates these.
Definition: b2ParticleGroup.h:134
float32 dampingStrength
Definition: b2ParticleSystem.h:119
An axis aligned bounding box.
Definition: b2Collision.h:162
int32 indexA
Indices of the respective particles making contact.
Definition: b2ParticleSystem.h:48
int32 DestroyParticlesInShape(const b2Shape &shape, const b2Transform &xf)
Definition: b2ParticleSystem.h:238
void SetFlagsBuffer(uint32 *buffer, int32 capacity)
Definition: b2ParticleSystem.cpp:3589
float32 GetGravityScale() const
Get the particle gravity scale.
Definition: b2ParticleSystem.h:994
This is an internal structure.
Definition: b2TimeStep.h:39
b2Vec2 * GetPositionBuffer()
Definition: b2ParticleSystem.h:1059
Less compressibility.
Definition: b2Particle.h:56
int32 GetParticleGroupCount() const
Get the number of particle groups.
Definition: b2ParticleSystem.h:901
float32 viscousStrength
Definition: b2ParticleSystem.h:131
int32 GetMaxParticleCount() const
Get the maximum number of particles.
Definition: b2ParticleSystem.h:1069
bool destroyByAge
Definition: b2ParticleSystem.h:178
void DestroyOldestParticle(const int32 index, const bool callDestructionListener)
Definition: b2ParticleSystem.cpp:770
Definition: b2ParticleSystem.h:63
void SetRadius(float32 radius)
Definition: b2ParticleSystem.h:971
int32 GetStaticPressureIterations() const
Get the number of iterations for static pressure of particles.
Definition: b2ParticleSystem.h:1014
#define b2_particleStride
The default distance between particles, multiplied by the particle diameter.
Definition: b2Settings.h:156
A rigid body. These are created via b2World::CreateBody.
Definition: b2Body.h:127
bool GetPaused() const
Definition: b2ParticleSystem.h:916
void SetStaticPressureIterations(int32 iterations)
Definition: b2ParticleSystem.h:1009
float32 surfaceTensionNormalStrength
Definition: b2ParticleSystem.h:140
void SetDestructionByAge(const bool enable)
Definition: b2ParticleSystem.cpp:3554
With restitution from stretching.
Definition: b2Particle.h:40
void SetStuckThreshold(int32 iterations)
Definition: b2ParticleSystem.cpp:3861
float32 staticPressureStrength
Definition: b2ParticleSystem.h:160
b2ParticleGroup *const * GetGroupBuffer()
Definition: b2ParticleSystem.h:1110
b2Body * body
The body making contact.
Definition: b2ParticleSystem.h:69
int32 CreateParticle(const b2ParticleDef &def)
Definition: b2ParticleSystem.cpp:627
float32 springStrength
Definition: b2ParticleSystem.h:127
Definition: b2ParticleSystem.h:45
A 2D column vector.
Definition: b2Math.h:56
void JoinParticleGroups(b2ParticleGroup *groupA, b2ParticleGroup *groupB)
Definition: b2ParticleSystem.cpp:1102
#define b2_invalidParticleIndex
A symbolic constant that stands for particle allocation error.
Definition: b2Settings.h:153
void ApplyLinearImpulse(int32 firstIndex, int32 lastIndex, const b2Vec2 &impulse)
Definition: b2ParticleSystem.cpp:3725
float32 surfaceTensionPressureStrength
Definition: b2ParticleSystem.h:135
float32 GetDamping() const
Get damping for particles.
Definition: b2ParticleSystem.h:1004
float32 elasticStrength
Definition: b2ParticleSystem.h:123
float32 GetDensity() const
Get the particle density.
Definition: b2ParticleSystem.h:984
Definition: b2WorldCallbacks.h:208
void SetStrictContactCheck(bool enabled)
Definition: b2ParticleSystem.h:961
b2ParticleSystem * GetNext()
Get the next particle-system in the world's particle-system list.
Definition: b2ParticleSystem.h:941
void DestroyParticle(int32 index)
Definition: b2ParticleSystem.h:207
void QueryAABB(b2QueryCallback *callback, const b2AABB &aabb) const
Definition: b2ParticleSystem.cpp:3737
const int32 * GetIndexByExpirationTimeBuffer()
Definition: b2ParticleSystem.cpp:3539
Definition: b2Particle.h:320
void SetGravityScale(float32 gravityScale)
Definition: b2ParticleSystem.h:989
Definition: b2Fixture.h:108