123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /*
- * 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
- #define B2_PARTICLE
- #include <Box2D/Common/b2Math.h>
- #include <Box2D/Common/b2Settings.h>
- #include <Box2D/Common/b2IntrusiveList.h>
- struct b2Color;
- class b2ParticleGroup;
- /// @file
- /// The particle type. Can be combined with the | operator.
- enum b2ParticleFlag
- {
- /// Water particle.
- b2_waterParticle = 0,
- /// Removed after next simulation step.
- b2_zombieParticle = 1 << 1,
- /// Zero velocity.
- b2_wallParticle = 1 << 2,
- /// With restitution from stretching.
- b2_springParticle = 1 << 3,
- /// With restitution from deformation.
- b2_elasticParticle = 1 << 4,
- /// With viscosity.
- b2_viscousParticle = 1 << 5,
- /// Without isotropic pressure.
- b2_powderParticle = 1 << 6,
- /// With surface tension.
- b2_tensileParticle = 1 << 7,
- /// Mix color between contacting particles.
- b2_colorMixingParticle = 1 << 8,
- /// Call b2DestructionListener on destruction.
- b2_destructionListenerParticle = 1 << 9,
- /// Prevents other particles from leaking.
- b2_barrierParticle = 1 << 10,
- /// Less compressibility.
- b2_staticPressureParticle = 1 << 11,
- /// Makes pairs or triads with other particles.
- b2_reactiveParticle = 1 << 12,
- /// With high repulsive force.
- b2_repulsiveParticle = 1 << 13,
- /// Call b2ContactListener when this particle is about to interact with
- /// a rigid body or stops interacting with a rigid body.
- /// This results in an expensive operation compared to using
- /// b2_fixtureContactFilterParticle to detect collisions between
- /// particles.
- b2_fixtureContactListenerParticle = 1 << 14,
- /// Call b2ContactListener when this particle is about to interact with
- /// another particle or stops interacting with another particle.
- /// This results in an expensive operation compared to using
- /// b2_particleContactFilterParticle to detect collisions between
- /// particles.
- b2_particleContactListenerParticle = 1 << 15,
- /// Call b2ContactFilter when this particle interacts with rigid bodies.
- b2_fixtureContactFilterParticle = 1 << 16,
- /// Call b2ContactFilter when this particle interacts with other
- /// particles.
- b2_particleContactFilterParticle = 1 << 17,
- };
- /// Small color object for each particle
- class b2ParticleColor
- {
- public:
- b2ParticleColor() {}
- /// Constructor with four elements: r (red), g (green), b (blue), and a
- /// (opacity).
- /// Each element can be specified 0 to 255.
- b2Inline b2ParticleColor(uint8 r, uint8 g, uint8 b, uint8 a)
- {
- Set(r, g, b, a);
- }
- /// Constructor that initializes the above four elements with the value of
- /// the b2Color object.
- b2ParticleColor(const b2Color& color);
- /// True when all four color elements equal 0. When true, a particle color
- /// buffer isn't allocated by CreateParticle().
- ///
- bool IsZero() const
- {
- return !r && !g && !b && !a;
- }
- /// Used internally to convert the value of b2Color.
- ///
- b2Color GetColor() const;
- /// Sets color for current object using the four elements described above.
- ///
- b2Inline void Set(uint8 r_, uint8 g_, uint8 b_, uint8 a_)
- {
- r = r_;
- g = g_;
- b = b_;
- a = a_;
- }
- /// Initializes the object with the value of the b2Color.
- ///
- void Set(const b2Color& color);
- /// Assign a b2ParticleColor to this instance.
- b2ParticleColor& operator = (const b2ParticleColor &color)
- {
- Set(color.r, color.g, color.b, color.a);
- return *this;
- }
- /// Multiplies r, g, b, a members by s where s is a value between 0.0
- /// and 1.0.
- b2ParticleColor& operator *= (float32 s)
- {
- Set((uint8)(r * s), (uint8)(g * s), (uint8)(b * s), (uint8)(a * s));
- return *this;
- }
- /// Scales r, g, b, a members by s where s is a value between 0 and 255.
- b2ParticleColor& operator *= (uint8 s)
- {
- // 1..256 to maintain the complete dynamic range.
- const int32 scale = (int32)s + 1;
- Set((uint8)(((int32)r * scale) >> k_bitsPerComponent),
- (uint8)(((int32)g * scale) >> k_bitsPerComponent),
- (uint8)(((int32)b * scale) >> k_bitsPerComponent),
- (uint8)(((int32)a * scale) >> k_bitsPerComponent));
- return *this;
- }
- /// Scales r, g, b, a members by s returning the modified b2ParticleColor.
- b2ParticleColor operator * (float32 s) const
- {
- return MultiplyByScalar(s);
- }
- /// Scales r, g, b, a members by s returning the modified b2ParticleColor.
- b2ParticleColor operator * (uint8 s) const
- {
- return MultiplyByScalar(s);
- }
- /// Add two colors. This is a non-saturating addition so values
- /// overflows will wrap.
- b2Inline b2ParticleColor& operator += (const b2ParticleColor &color)
- {
- r += color.r;
- g += color.g;
- b += color.b;
- a += color.a;
- return *this;
- }
- /// Add two colors. This is a non-saturating addition so values
- /// overflows will wrap.
- b2ParticleColor operator + (const b2ParticleColor &color) const
- {
- b2ParticleColor newColor(*this);
- newColor += color;
- return newColor;
- }
- /// Subtract a color from this color. This is a subtraction without
- /// saturation so underflows will wrap.
- b2Inline b2ParticleColor& operator -= (const b2ParticleColor &color)
- {
- r -= color.r;
- g -= color.g;
- b -= color.b;
- a -= color.a;
- return *this;
- }
- /// Subtract a color from this color returning the result. This is a
- /// subtraction without saturation so underflows will wrap.
- b2ParticleColor operator - (const b2ParticleColor &color) const
- {
- b2ParticleColor newColor(*this);
- newColor -= color;
- return newColor;
- }
- /// Compare this color with the specified color.
- bool operator == (const b2ParticleColor &color) const
- {
- return r == color.r && g == color.g && b == color.b && a == color.a;
- }
- /// Mix mixColor with this color using strength to control how much of
- /// mixColor is mixed with this color and vice versa. The range of
- /// strength is 0..128 where 0 results in no color mixing and 128 results
- /// in an equal mix of both colors. strength 0..128 is analogous to an
- /// alpha channel value between 0.0f..0.5f.
- b2Inline void Mix(b2ParticleColor * const mixColor, const int32 strength)
- {
- MixColors(this, mixColor, strength);
- }
- /// Mix colorA with colorB using strength to control how much of
- /// colorA is mixed with colorB and vice versa. The range of
- /// strength is 0..128 where 0 results in no color mixing and 128 results
- /// in an equal mix of both colors. strength 0..128 is analogous to an
- /// alpha channel value between 0.0f..0.5f.
- static b2Inline void MixColors(b2ParticleColor * const colorA,
- b2ParticleColor * const colorB,
- const int32 strength)
- {
- const uint8 dr = (uint8)((strength * (colorB->r - colorA->r)) >>
- k_bitsPerComponent);
- const uint8 dg = (uint8)((strength * (colorB->g - colorA->g)) >>
- k_bitsPerComponent);
- const uint8 db = (uint8)((strength * (colorB->b - colorA->b)) >>
- k_bitsPerComponent);
- const uint8 da = (uint8)((strength * (colorB->a - colorA->a)) >>
- k_bitsPerComponent);
- colorA->r += dr;
- colorA->g += dg;
- colorA->b += db;
- colorA->a += da;
- colorB->r -= dr;
- colorB->g -= dg;
- colorB->b -= db;
- colorB->a -= da;
- }
- private:
- /// Generalization of the multiply operator using a scalar in-place
- /// multiplication.
- template <typename T>
- b2ParticleColor MultiplyByScalar(T s) const
- {
- b2ParticleColor color(*this);
- color *= s;
- return color;
- }
- public:
- uint8 r, g, b, a;
- protected:
- /// Maximum value of a b2ParticleColor component.
- static const float32 k_maxValue;
- /// 1.0 / k_maxValue.
- static const float32 k_inverseMaxValue;
- /// Number of bits used to store each b2ParticleColor component.
- static const uint8 k_bitsPerComponent;
- };
- extern b2ParticleColor b2ParticleColor_zero;
- /// A particle definition holds all the data needed to construct a particle.
- /// You can safely re-use these definitions.
- struct b2ParticleDef
- {
- b2ParticleDef()
- {
- flags = 0;
- position = b2Vec2_zero;
- velocity = b2Vec2_zero;
- color = b2ParticleColor_zero;
- lifetime = 0.0f;
- userData = NULL;
- group = NULL;
- }
- #if LIQUIDFUN_EXTERNAL_LANGUAGE_API
- /// 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
- /// \brief Specifies the type of particle (see #b2ParticleFlag).
- ///
- /// A particle may be more than one type.
- /// Multiple types are chained by logical sums, for example:
- /// pd.flags = b2_elasticParticle | b2_viscousParticle
- uint32 flags;
- /// The world position of the particle.
- b2Vec2 position;
- /// The linear velocity of the particle in world co-ordinates.
- b2Vec2 velocity;
- /// The color of the particle.
- b2ParticleColor color;
- /// Lifetime of the particle in seconds. A value <= 0.0f indicates a
- /// particle with infinite lifetime.
- float32 lifetime;
- /// Use this to store application-specific body data.
- void* userData;
- /// An existing particle group to which the particle will be added.
- b2ParticleGroup* group;
- };
- /// A helper function to calculate the optimal number of iterations.
- int32 b2CalculateParticleIterations(
- float32 gravity, float32 radius, float32 timeStep);
- /// Handle to a particle. Particle indices are ephemeral: the same index might
- /// refer to a different particle, from frame-to-frame. If you need to keep a
- /// reference to a particular particle across frames, you should acquire a
- /// b2ParticleHandle. Use #b2ParticleSystem::GetParticleHandleFromIndex() to
- /// retrieve the b2ParticleHandle of a particle from the particle system.
- class b2ParticleHandle : public b2TypedIntrusiveListNode<b2ParticleHandle>
- {
- // Allow b2ParticleSystem to use SetIndex() to associate particle handles
- // with particle indices.
- friend class b2ParticleSystem;
- public:
- /// Initialize the index associated with the handle to an invalid index.
- b2ParticleHandle() : m_index(b2_invalidParticleIndex) { }
- /// Empty destructor.
- ~b2ParticleHandle() { }
- /// Get the index of the particle associated with this handle.
- int32 GetIndex() const { return m_index; }
- private:
- /// Set the index of the particle associated with this handle.
- void SetIndex(int32 index) { m_index = index; }
- private:
- // Index of the particle within the particle system.
- int32 m_index;
- };
- #if LIQUIDFUN_EXTERNAL_LANGUAGE_API
- inline void b2ParticleDef::SetPosition(float32 x, float32 y)
- {
- position.Set(x, y);
- }
- inline void b2ParticleDef::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
|