axmol/thirdparty/box2d-optimized/include/box2d/b2_particle_group.h

414 lines
11 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_PARTICLE_GROUP
#define B2_PARTICLE_GROUP
#include "b2_particle.h"
class b2Shape;
class b2World;
class b2ParticleSystem;
class b2ParticleGroup;
class b2ParticleColor;
#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
class b2CircleShape;
#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
/// @file
/// The particle group type. Can be combined with the | operator.
enum b2ParticleGroupFlag
{
/// Prevents overlapping or leaking.
b2_solidParticleGroup = 1 << 0,
/// Keeps its shape.
b2_rigidParticleGroup = 1 << 1,
/// Won't be destroyed if it gets empty.
b2_particleGroupCanBeEmpty = 1 << 2,
/// Will be destroyed on next simulation step.
b2_particleGroupWillBeDestroyed = 1 << 3,
/// Updates depth data on next simulation step.
b2_particleGroupNeedsUpdateDepth = 1 << 4,
b2_particleGroupInternalMask =
b2_particleGroupWillBeDestroyed |
b2_particleGroupNeedsUpdateDepth,
};
/// A particle group definition holds all the data needed to construct a
/// particle group. You can safely re-use these definitions.
struct b2ParticleGroupDef
{
b2ParticleGroupDef()
{
flags = 0;
groupFlags = 0;
position = b2Vec2_zero;
angle = 0;
linearVelocity = b2Vec2_zero;
angularVelocity = 0;
color = b2ParticleColor_zero;
strength = 1;
shape = NULL;
shapes = NULL;
shapeCount = 0;
stride = 0;
particleCount = 0;
positionData = NULL;
lifetime = 0.0f;
userData = NULL;
group = NULL;
#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
circleShapes = NULL;
ownShapesArray = false;
#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
}
~b2ParticleGroupDef()
{
#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
FreeShapesMemory();
#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
}
/// The particle-behavior flags (See #b2ParticleFlag).
uint32 flags;
/// The group-construction flags (See #b2ParticleGroupFlag).
uint32 groupFlags;
/// The world position of the group.
/// Moves the group's shape a distance equal to the value of position.
b2Vec2 position;
/// The world angle of the group in radians.
/// Rotates the shape by an angle equal to the value of angle.
float32 angle;
/// The linear velocity of the group's origin in world co-ordinates.
b2Vec2 linearVelocity;
/// The angular velocity of the group.
float32 angularVelocity;
/// The color of all particles in the group.
b2ParticleColor color;
/// The strength of cohesion among the particles in a group with flag
/// b2_elasticParticle or b2_springParticle.
float32 strength;
/// The shape where particles will be added.
const b2Shape* shape;
/// A array of shapes where particles will be added.
const b2Shape* const* shapes;
/// The number of shapes.
int32 shapeCount;
/// The interval of particles in the shape.
/// If it is 0, b2_particleStride * particleDiameter is used instead.
float32 stride;
/// The number of particles in addition to ones added in the shape.
int32 particleCount;
/// The initial positions of the particleCount particles.
const b2Vec2* positionData;
/// Lifetime of the particle group in seconds. A value <= 0.0f indicates a
/// particle group with infinite lifetime.
float32 lifetime;
/// Use this to store application-specific group data.
void* userData;
/// An existing particle group to which the particles will be added.
b2ParticleGroup* group;
#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
/// Storage for constructed CircleShapes from an incoming vertex list
const b2CircleShape* circleShapes;
/// True if we create the shapes array internally.
bool ownShapesArray;
/// Clean up all memory associated with SetCircleShapesFromVertexList
void FreeShapesMemory();
/// From a vertex list created by an external language API, construct
/// a list of circle shapes that can be used to create a b2ParticleGroup
/// This eliminates cumbersome array-interfaces between languages.
void SetCircleShapesFromVertexList(void* inBuf,
int numShapes,
float radius);
/// Set position with direct floats.
void SetPosition(float32 x, float32 y);
/// Set color with direct ints.
void SetColor(int32 r, int32 g, int32 b, int32 a);
#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
};
/// A group of particles. b2ParticleGroup::CreateParticleGroup creates these.
class b2ParticleGroup
{
public:
/// Get the next particle group from the list in b2_World.
b2ParticleGroup* GetNext();
const b2ParticleGroup* GetNext() const;
/// Get the particle system that holds this particle group.
b2ParticleSystem* GetParticleSystem();
const b2ParticleSystem* GetParticleSystem() const;
/// Get the number of particles.
int32 GetParticleCount() const;
/// Get the offset of this group in the global particle buffer
int32 GetBufferIndex() const;
/// Does this group contain the particle.
bool ContainsParticle(int32 index) const;
/// Get the logical sum of particle flags.
uint32 GetAllParticleFlags() const;
/// Get the construction flags for the group.
uint32 GetGroupFlags() const;
/// Set the construction flags for the group.
void SetGroupFlags(uint32 flags);
/// Get the total mass of the group: the sum of all particles in it.
float32 GetMass() const;
/// Get the moment of inertia for the group.
float32 GetInertia() const;
/// Get the center of gravity for the group.
b2Vec2 GetCenter() const;
/// Get the linear velocity of the group.
b2Vec2 GetLinearVelocity() const;
/// Get the angular velocity of the group.
float32 GetAngularVelocity() const;
/// Get the position of the group's origin and rotation.
/// Used only with groups of rigid particles.
const b2Transform& GetTransform() const;
/// Get position of the particle group as a whole.
/// Used only with groups of rigid particles.
const b2Vec2& GetPosition() const;
/// Get the rotational angle of the particle group as a whole.
/// Used only with groups of rigid particles.
float32 GetAngle() const;
/// Get the world linear velocity of a world point, from the average linear
/// and angular velocities of the particle group.
/// @param a point in world coordinates.
/// @return the world velocity of a point.
b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;
/// Get the user data pointer that was provided in the group definition.
void* GetUserData() const;
/// Set the user data. Use this to store your application specific data.
void SetUserData(void* data);
/// Call b2ParticleSystem::ApplyForce for every particle in the group.
void ApplyForce(const b2Vec2& force);
/// Call b2ParticleSystem::ApplyLinearImpulse for every particle in the
/// group.
void ApplyLinearImpulse(const b2Vec2& impulse);
/// Destroy all the particles in this group.
/// This function is locked during callbacks.
/// @param Whether to call the world b2DestructionListener for each
/// particle is destroyed.
/// @warning This function is locked during callbacks.
void DestroyParticles(bool callDestructionListener);
/// Destroy all particles in this group without enabling the destruction
/// callback for destroyed particles.
/// This function is locked during callbacks.
/// @warning This function is locked during callbacks.
void DestroyParticles();
private:
friend class b2ParticleSystem;
b2ParticleSystem* m_system;
int32 m_firstIndex, m_lastIndex;
uint32 m_groupFlags;
float32 m_strength;
b2ParticleGroup* m_prev;
b2ParticleGroup* m_next;
mutable int32 m_timestamp;
mutable float32 m_mass;
mutable float32 m_inertia;
mutable b2Vec2 m_center;
mutable b2Vec2 m_linearVelocity;
mutable float32 m_angularVelocity;
mutable b2Transform m_transform;
void* m_userData;
b2ParticleGroup();
~b2ParticleGroup();
void UpdateStatistics() const;
};
inline b2ParticleGroup* b2ParticleGroup::GetNext()
{
return m_next;
}
inline const b2ParticleGroup* b2ParticleGroup::GetNext() const
{
return m_next;
}
inline b2ParticleSystem* b2ParticleGroup::GetParticleSystem()
{
return m_system;
}
inline const b2ParticleSystem* b2ParticleGroup::GetParticleSystem() const
{
return m_system;
}
inline int32 b2ParticleGroup::GetParticleCount() const
{
return m_lastIndex - m_firstIndex;
}
inline bool b2ParticleGroup::ContainsParticle(int32 index) const
{
return m_firstIndex <= index && index < m_lastIndex;
}
inline b2ParticleGroup::~b2ParticleGroup()
{
}
inline int32 b2ParticleGroup::GetBufferIndex() const
{
return m_firstIndex;
}
inline uint32 b2ParticleGroup::GetGroupFlags() const
{
return m_groupFlags & ~b2_particleGroupInternalMask;
}
inline float32 b2ParticleGroup::GetMass() const
{
UpdateStatistics();
return m_mass;
}
inline float32 b2ParticleGroup::GetInertia() const
{
UpdateStatistics();
return m_inertia;
}
inline b2Vec2 b2ParticleGroup::GetCenter() const
{
UpdateStatistics();
return m_center;
}
inline b2Vec2 b2ParticleGroup::GetLinearVelocity() const
{
UpdateStatistics();
return m_linearVelocity;
}
inline float32 b2ParticleGroup::GetAngularVelocity() const
{
UpdateStatistics();
return m_angularVelocity;
}
inline const b2Transform& b2ParticleGroup::GetTransform() const
{
return m_transform;
}
inline const b2Vec2& b2ParticleGroup::GetPosition() const
{
return m_transform.p;
}
inline float32 b2ParticleGroup::GetAngle() const
{
return m_transform.q.GetAngle();
}
inline b2Vec2 b2ParticleGroup::GetLinearVelocityFromWorldPoint(
const b2Vec2& worldPoint) const
{
UpdateStatistics();
return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_center);
}
inline void* b2ParticleGroup::GetUserData() const
{
return m_userData;
}
inline void b2ParticleGroup::SetUserData(void* data)
{
m_userData = data;
}
inline void b2ParticleGroup::DestroyParticles()
{
DestroyParticles(false);
}
#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
inline void b2ParticleGroupDef::SetPosition(float32 x, float32 y)
{
position.Set(x, y);
}
inline void b2ParticleGroupDef::SetColor(int32 r, int32 g, int32 b, int32 a)
{
color.Set((uint8)r, (uint8)g, (uint8)b, (uint8)a);
}
#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
#endif