mirror of
https://github.com/Bithack/principia.git
synced 2026-06-24 02:04:08 +00:00
332 lines
9.6 KiB
C++
332 lines
9.6 KiB
C++
/*
|
|
* Copyright (c) 2013 Google, Inc.
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any damages
|
|
* arising from the use of this software.
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software. If you use this software
|
|
* in a product, an acknowledgment in the product documentation would be
|
|
* appreciated but is not required.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
#ifndef B2_PARTICLb2_SYSTEM_H
|
|
#define B2_PARTICLb2_SYSTEM_H
|
|
|
|
#include <Box2D/Particle/b2Particle.h>
|
|
#include <Box2D/Dynamics/b2TimeStep.h>
|
|
|
|
/// You need not to directly access b2ParticleSystem.
|
|
/// To access particle data, use functions in b2World or b2ParticleGroup.
|
|
|
|
class b2World;
|
|
class b2Body;
|
|
class b2Shape;
|
|
class b2ParticleGroup;
|
|
class b2BlockAllocator;
|
|
class b2StackAllocator;
|
|
class b2QueryCallback;
|
|
class b2RayCastCallback;
|
|
struct b2ParticleGroupDef;
|
|
struct b2Vec2;
|
|
struct b2AABB;
|
|
|
|
struct b2ParticleContact
|
|
{
|
|
///Indices of the respective particles making contact.
|
|
///
|
|
int32 indexA, indexB;
|
|
///The logical sum of the particle behaviors that have been set.
|
|
///
|
|
uint32 flags;
|
|
/// Weight of the contact. A value between 0.0f and 1.0f.
|
|
///
|
|
float32 weight;
|
|
///The normalized direction from A to B.
|
|
///
|
|
b2Vec2 normal;
|
|
};
|
|
|
|
struct b2ParticleBodyContact
|
|
{
|
|
/// Index of the particle making contact.
|
|
///
|
|
int32 index;
|
|
/// The body making contact.
|
|
///
|
|
b2Body* body;
|
|
///Weight of the contact. A value between 0.0f and 1.0f.
|
|
///
|
|
float32 weight;
|
|
/// The normalized direction from the particle to the body.
|
|
///
|
|
b2Vec2 normal;
|
|
/// The effective mass used in calculating force.
|
|
///
|
|
float32 mass;
|
|
};
|
|
|
|
class b2ParticleSystem
|
|
{
|
|
|
|
private:
|
|
|
|
friend class b2World;
|
|
friend class b2ParticleGroup;
|
|
|
|
template <typename T>
|
|
struct ParticleBuffer
|
|
{
|
|
ParticleBuffer()
|
|
{
|
|
data = NULL;
|
|
userSuppliedCapacity = 0;
|
|
}
|
|
T* data;
|
|
int32 userSuppliedCapacity;
|
|
};
|
|
|
|
/// Used for detecting particle contacts
|
|
struct Proxy
|
|
{
|
|
int32 index;
|
|
uint32 tag;
|
|
friend inline bool operator<(const Proxy &a, const Proxy &b)
|
|
{
|
|
return a.tag < b.tag;
|
|
}
|
|
friend inline bool operator<(uint32 a, const Proxy &b)
|
|
{
|
|
return a < b.tag;
|
|
}
|
|
friend inline bool operator<(const Proxy &a, uint32 b)
|
|
{
|
|
return a.tag < b;
|
|
}
|
|
};
|
|
|
|
/// Connection between two particles
|
|
struct Pair
|
|
{
|
|
int32 indexA, indexB;
|
|
uint32 flags;
|
|
float32 strength;
|
|
float32 distance;
|
|
};
|
|
|
|
/// Connection between three particles
|
|
struct Triad
|
|
{
|
|
int32 indexA, indexB, indexC;
|
|
uint32 flags;
|
|
float32 strength;
|
|
b2Vec2 pa, pb, pc;
|
|
float32 ka, kb, kc, s;
|
|
};
|
|
|
|
// Callback used with b2VoronoiDiagram.
|
|
class CreateParticleGroupCallback
|
|
{
|
|
public:
|
|
void operator()(int32 a, int32 b, int32 c) const;
|
|
b2ParticleSystem* system;
|
|
const b2ParticleGroupDef* def;
|
|
int32 firstIndex;
|
|
};
|
|
|
|
// Callback used with b2VoronoiDiagram.
|
|
class JoinParticleGroupsCallback
|
|
{
|
|
public:
|
|
void operator()(int32 a, int32 b, int32 c) const;
|
|
b2ParticleSystem* system;
|
|
b2ParticleGroup* groupA;
|
|
b2ParticleGroup* groupB;
|
|
};
|
|
|
|
/// All particle types that require creating pairs
|
|
static const int32 k_pairFlags =
|
|
b2_springParticle;
|
|
/// All particle types that require creating triads
|
|
static const int32 k_triadFlags =
|
|
b2_elasticParticle;
|
|
/// All particle types that require computing depth
|
|
static const int32 k_noPressureFlags =
|
|
b2_powderParticle;
|
|
|
|
b2ParticleSystem();
|
|
~b2ParticleSystem();
|
|
|
|
template <typename T> T* ReallocateBuffer(T* buffer, int32 oldCapacity, int32 newCapacity);
|
|
template <typename T> T* ReallocateBuffer(T* buffer, int32 userSuppliedCapacity, int32 oldCapacity, int32 newCapacity, bool deferred);
|
|
template <typename T> T* ReallocateBuffer(ParticleBuffer<T>* buffer, int32 oldCapacity, int32 newCapacity, bool deferred);
|
|
template <typename T> T* RequestParticleBuffer(T* buffer);
|
|
|
|
int32 CreateParticle(const b2ParticleDef& def);
|
|
void DestroyParticle(int32 index, bool callDestructionListener);
|
|
// Destroy particles in the specified shape with the transform xf applied
|
|
// optionally calling the destruction listener for particles that are
|
|
// destroyed.
|
|
int32 DestroyParticlesInShape(const b2Shape& shape, const b2Transform& xf,
|
|
bool callDestructionListener);
|
|
void DestroyParticlesInGroup(b2ParticleGroup* group,
|
|
bool callDestructionListener);
|
|
b2ParticleGroup* CreateParticleGroup(const b2ParticleGroupDef& def);
|
|
void JoinParticleGroups(b2ParticleGroup* groupA, b2ParticleGroup* groupB);
|
|
void DestroyParticleGroup(b2ParticleGroup* group);
|
|
void ComputeDepthForGroup(b2ParticleGroup* group);
|
|
|
|
void AddContact(int32 a, int32 b);
|
|
void UpdateContacts(bool exceptZombie);
|
|
void UpdateBodyContacts();
|
|
|
|
void Solve(const b2TimeStep& step);
|
|
void SolveCollision(const b2TimeStep& step);
|
|
void SolvePressure(const b2TimeStep& step);
|
|
void SolveDamping(const b2TimeStep& step);
|
|
void SolveWall(const b2TimeStep& step);
|
|
void SolveRigid(const b2TimeStep& step);
|
|
void SolveElastic(const b2TimeStep& step);
|
|
void SolveSpring(const b2TimeStep& step);
|
|
void SolveTensile(const b2TimeStep& step);
|
|
void SolveViscous(const b2TimeStep& step);
|
|
void SolvePowder(const b2TimeStep& step);
|
|
void SolveSolid(const b2TimeStep& step);
|
|
void SolveColorMixing(const b2TimeStep& step);
|
|
void SolveZombie();
|
|
void RotateBuffer(int32 start, int32 mid, int32 end);
|
|
|
|
void SetParticleRadius(float32 radius);
|
|
float32 GetParticleRadius() const;
|
|
void SetParticleDensity(float32 density);
|
|
float32 GetParticleDensity() const;
|
|
void SetParticleGravityScale(float32 gravityScale);
|
|
float32 GetParticleGravityScale() const;
|
|
void SetParticleDamping(float32 damping);
|
|
float32 GetParticleDamping() const;
|
|
float32 GetCriticalVelocity(const b2TimeStep& step) const;
|
|
float32 GetCriticalVelocitySquared(const b2TimeStep& step) const;
|
|
float32 GetCriticalPressure(const b2TimeStep& step) const;
|
|
float32 GetParticleStride() const;
|
|
float32 GetParticleMass() const;
|
|
float32 GetParticleInvMass() const;
|
|
|
|
b2ParticleGroup* GetParticleGroupList();
|
|
const b2ParticleGroup* GetParticleGroupList() const;
|
|
int32 GetParticleGroupCount() const;
|
|
int32 GetParticleCount() const;
|
|
int32 GetParticleMaxCount() const;
|
|
void SetParticleMaxCount(int32 count);
|
|
uint32* GetParticleFlagsBuffer();
|
|
float32* GetParticleAccumulationBuffer();
|
|
b2Vec2* GetParticlePositionBuffer();
|
|
b2Vec2* GetParticleVelocityBuffer();
|
|
b2ParticleColor* GetParticleColorBuffer();
|
|
void** GetParticleUserDataBuffer();
|
|
const uint32* GetParticleFlagsBuffer() const;
|
|
const b2Vec2* GetParticlePositionBuffer() const;
|
|
const b2Vec2* GetParticleVelocityBuffer() const;
|
|
const b2ParticleColor* GetParticleColorBuffer() const;
|
|
const b2ParticleGroup* const* GetParticleGroupBuffer() const;
|
|
void* const* GetParticleUserDataBuffer() const;
|
|
template <typename T> void SetParticleBuffer(ParticleBuffer<T>* buffer, T* newBufferData, int32 newCapacity);
|
|
void SetParticleFlagsBuffer(uint32* buffer, int32 capacity);
|
|
void SetParticlePositionBuffer(b2Vec2* buffer, int32 capacity);
|
|
void SetParticleVelocityBuffer(b2Vec2* buffer, int32 capacity);
|
|
void SetParticleColorBuffer(b2ParticleColor* buffer, int32 capacity);
|
|
b2ParticleGroup* const* GetParticleGroupBuffer();
|
|
void SetParticleUserDataBuffer(void** buffer, int32 capacity);
|
|
|
|
void QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const;
|
|
void RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const;
|
|
float32 ComputeParticleCollisionEnergy() const;
|
|
|
|
int32 m_timestamp;
|
|
int32 m_allParticleFlags;
|
|
int32 m_allGroupFlags;
|
|
float32 m_density;
|
|
float32 m_inverseDensity;
|
|
float32 m_gravityScale;
|
|
float32 m_particleDiameter;
|
|
float32 m_inverseDiameter;
|
|
float32 m_squaredDiameter;
|
|
|
|
int32 m_count;
|
|
int32 m_internalAllocatedCapacity;
|
|
int32 m_maxCount;
|
|
ParticleBuffer<uint32> m_flagsBuffer;
|
|
ParticleBuffer<b2Vec2> m_positionBuffer;
|
|
ParticleBuffer<b2Vec2> m_velocityBuffer;
|
|
float32* m_dataBuffer;
|
|
float32* m_accumulationBuffer; // temporary values
|
|
b2Vec2* m_accumulation2Buffer; // temporary vector values
|
|
float32* m_depthBuffer; // distance from the surface
|
|
ParticleBuffer<b2ParticleColor> m_colorBuffer;
|
|
b2ParticleGroup** m_groupBuffer;
|
|
ParticleBuffer<void*> m_userDataBuffer;
|
|
|
|
int32 m_proxyCount;
|
|
int32 m_proxyCapacity;
|
|
Proxy* m_proxyBuffer;
|
|
|
|
public:
|
|
int32 m_contactCount;
|
|
int32 m_contactCapacity;
|
|
b2ParticleContact* m_contactBuffer;
|
|
private:
|
|
|
|
int32 m_bodyContactCount;
|
|
int32 m_bodyContactCapacity;
|
|
b2ParticleBodyContact* m_bodyContactBuffer;
|
|
|
|
int32 m_pairCount;
|
|
int32 m_pairCapacity;
|
|
Pair* m_pairBuffer;
|
|
|
|
int32 m_triadCount;
|
|
int32 m_triadCapacity;
|
|
Triad* m_triadBuffer;
|
|
|
|
int32 m_groupCount;
|
|
b2ParticleGroup* m_groupList;
|
|
|
|
float32 m_pressureStrength;
|
|
float32 m_dampingStrength;
|
|
float32 m_elasticStrength;
|
|
float32 m_springStrength;
|
|
float32 m_viscousStrength;
|
|
float32 m_surfaceTensionStrengthA;
|
|
float32 m_surfaceTensionStrengthB;
|
|
float32 m_powderStrength;
|
|
float32 m_ejectionStrength;
|
|
float32 m_colorMixingStrength;
|
|
|
|
b2World* m_world;
|
|
};
|
|
|
|
inline b2ParticleGroup* b2ParticleSystem::GetParticleGroupList()
|
|
{
|
|
return m_groupList;
|
|
}
|
|
|
|
inline const b2ParticleGroup* b2ParticleSystem::GetParticleGroupList() const
|
|
{
|
|
return m_groupList;
|
|
}
|
|
|
|
inline int32 b2ParticleSystem::GetParticleGroupCount() const
|
|
{
|
|
return m_groupCount;
|
|
}
|
|
|
|
inline int32 b2ParticleSystem::GetParticleCount() const
|
|
{
|
|
return m_count;
|
|
}
|
|
|
|
#endif
|