Home | History | Annotate | Download | only in Dynamics
      1 /*
      2 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
      3 *
      4 * This software is provided 'as-is', without any express or implied
      5 * warranty.  In no event will the authors be held liable for any damages
      6 * arising from the use of this software.
      7 * Permission is granted to anyone to use this software for any purpose,
      8 * including commercial applications, and to alter it and redistribute it
      9 * freely, subject to the following restrictions:
     10 * 1. The origin of this software must not be misrepresented; you must not
     11 * claim that you wrote the original software. If you use this software
     12 * in a product, an acknowledgment in the product documentation would be
     13 * appreciated but is not required.
     14 * 2. Altered source versions must be plainly marked as such, and must not be
     15 * misrepresented as being the original software.
     16 * 3. This notice may not be removed or altered from any source distribution.
     17 */
     18 
     19 #ifndef B2_FIXTURE_H
     20 #define B2_FIXTURE_H
     21 
     22 #include <Box2D/Dynamics/b2Body.h>
     23 #include <Box2D/Collision/b2Collision.h>
     24 #include <Box2D/Collision/Shapes/b2Shape.h>
     25 
     26 class b2BlockAllocator;
     27 class b2Body;
     28 class b2BroadPhase;
     29 class b2Fixture;
     30 
     31 /// This holds contact filtering data.
     32 struct b2Filter
     33 {
     34 	b2Filter()
     35 	{
     36 		categoryBits = 0x0001;
     37 		maskBits = 0xFFFF;
     38 		groupIndex = 0;
     39 	}
     40 
     41 	/// The collision category bits. Normally you would just set one bit.
     42 	uint16 categoryBits;
     43 
     44 	/// The collision mask bits. This states the categories that this
     45 	/// shape would accept for collision.
     46 	uint16 maskBits;
     47 
     48 	/// Collision groups allow a certain group of objects to never collide (negative)
     49 	/// or always collide (positive). Zero means no collision group. Non-zero group
     50 	/// filtering always wins against the mask bits.
     51 	int16 groupIndex;
     52 };
     53 
     54 /// A fixture definition is used to create a fixture. This class defines an
     55 /// abstract fixture definition. You can reuse fixture definitions safely.
     56 struct b2FixtureDef
     57 {
     58 	/// The constructor sets the default fixture definition values.
     59 	b2FixtureDef()
     60 	{
     61 		shape = NULL;
     62 		userData = NULL;
     63 		friction = 0.2f;
     64 		restitution = 0.0f;
     65 		density = 0.0f;
     66 		isSensor = false;
     67 	}
     68 
     69 	/// The shape, this must be set. The shape will be cloned, so you
     70 	/// can create the shape on the stack.
     71 	const b2Shape* shape;
     72 
     73 	/// Use this to store application specific fixture data.
     74 	void* userData;
     75 
     76 	/// The friction coefficient, usually in the range [0,1].
     77 	float32 friction;
     78 
     79 	/// The restitution (elasticity) usually in the range [0,1].
     80 	float32 restitution;
     81 
     82 	/// The density, usually in kg/m^2.
     83 	float32 density;
     84 
     85 	/// A sensor shape collects contact information but never generates a collision
     86 	/// response.
     87 	bool isSensor;
     88 
     89 	/// Contact filtering data.
     90 	b2Filter filter;
     91 };
     92 
     93 /// This proxy is used internally to connect fixtures to the broad-phase.
     94 struct b2FixtureProxy
     95 {
     96 	b2AABB aabb;
     97 	b2Fixture* fixture;
     98 	int32 childIndex;
     99 	int32 proxyId;
    100 };
    101 
    102 /// A fixture is used to attach a shape to a body for collision detection. A fixture
    103 /// inherits its transform from its parent. Fixtures hold additional non-geometric data
    104 /// such as friction, collision filters, etc.
    105 /// Fixtures are created via b2Body::CreateFixture.
    106 /// @warning you cannot reuse fixtures.
    107 class b2Fixture
    108 {
    109 public:
    110 	/// Get the type of the child shape. You can use this to down cast to the concrete shape.
    111 	/// @return the shape type.
    112 	b2Shape::Type GetType() const;
    113 
    114 	/// Get the child shape. You can modify the child shape, however you should not change the
    115 	/// number of vertices because this will crash some collision caching mechanisms.
    116 	/// Manipulating the shape may lead to non-physical behavior.
    117 	b2Shape* GetShape();
    118 	const b2Shape* GetShape() const;
    119 
    120 	/// Set if this fixture is a sensor.
    121 	void SetSensor(bool sensor);
    122 
    123 	/// Is this fixture a sensor (non-solid)?
    124 	/// @return the true if the shape is a sensor.
    125 	bool IsSensor() const;
    126 
    127 	/// Set the contact filtering data. This will not update contacts until the next time
    128 	/// step when either parent body is active and awake.
    129 	/// This automatically calls Refilter.
    130 	void SetFilterData(const b2Filter& filter);
    131 
    132 	/// Get the contact filtering data.
    133 	const b2Filter& GetFilterData() const;
    134 
    135 	/// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
    136 	void Refilter();
    137 
    138 	/// Get the parent body of this fixture. This is NULL if the fixture is not attached.
    139 	/// @return the parent body.
    140 	b2Body* GetBody();
    141 	const b2Body* GetBody() const;
    142 
    143 	/// Get the next fixture in the parent body's fixture list.
    144 	/// @return the next shape.
    145 	b2Fixture* GetNext();
    146 	const b2Fixture* GetNext() const;
    147 
    148 	/// Get the user data that was assigned in the fixture definition. Use this to
    149 	/// store your application specific data.
    150 	void* GetUserData() const;
    151 
    152 	/// Set the user data. Use this to store your application specific data.
    153 	void SetUserData(void* data);
    154 
    155 	/// Test a point for containment in this fixture.
    156 	/// @param p a point in world coordinates.
    157 	bool TestPoint(const b2Vec2& p) const;
    158 
    159 	/// Cast a ray against this shape.
    160 	/// @param output the ray-cast results.
    161 	/// @param input the ray-cast input parameters.
    162 	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const;
    163 
    164 	/// Get the mass data for this fixture. The mass data is based on the density and
    165 	/// the shape. The rotational inertia is about the shape's origin. This operation
    166 	/// may be expensive.
    167 	void GetMassData(b2MassData* massData) const;
    168 
    169 	/// Set the density of this fixture. This will _not_ automatically adjust the mass
    170 	/// of the body. You must call b2Body::ResetMassData to update the body's mass.
    171 	void SetDensity(float32 density);
    172 
    173 	/// Get the density of this fixture.
    174 	float32 GetDensity() const;
    175 
    176 	/// Get the coefficient of friction.
    177 	float32 GetFriction() const;
    178 
    179 	/// Set the coefficient of friction. This will _not_ change the friction of
    180 	/// existing contacts.
    181 	void SetFriction(float32 friction);
    182 
    183 	/// Get the coefficient of restitution.
    184 	float32 GetRestitution() const;
    185 
    186 	/// Set the coefficient of restitution. This will _not_ change the restitution of
    187 	/// existing contacts.
    188 	void SetRestitution(float32 restitution);
    189 
    190 	/// Get the fixture's AABB. This AABB may be enlarge and/or stale.
    191 	/// If you need a more accurate AABB, compute it using the shape and
    192 	/// the body transform.
    193 	const b2AABB& GetAABB(int32 childIndex) const;
    194 
    195 	/// Dump this fixture to the log file.
    196 	void Dump(int32 bodyIndex);
    197 
    198 protected:
    199 
    200 	friend class b2Body;
    201 	friend class b2World;
    202 	friend class b2Contact;
    203 	friend class b2ContactManager;
    204 
    205 	b2Fixture();
    206 
    207 	// We need separation create/destroy functions from the constructor/destructor because
    208 	// the destructor cannot access the allocator (no destructor arguments allowed by C++).
    209 	void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def);
    210 	void Destroy(b2BlockAllocator* allocator);
    211 
    212 	// These support body activation/deactivation.
    213 	void CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf);
    214 	void DestroyProxies(b2BroadPhase* broadPhase);
    215 
    216 	void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2);
    217 
    218 	float32 m_density;
    219 
    220 	b2Fixture* m_next;
    221 	b2Body* m_body;
    222 
    223 	b2Shape* m_shape;
    224 
    225 	float32 m_friction;
    226 	float32 m_restitution;
    227 
    228 	b2FixtureProxy* m_proxies;
    229 	int32 m_proxyCount;
    230 
    231 	b2Filter m_filter;
    232 
    233 	bool m_isSensor;
    234 
    235 	void* m_userData;
    236 };
    237 
    238 inline b2Shape::Type b2Fixture::GetType() const
    239 {
    240 	return m_shape->GetType();
    241 }
    242 
    243 inline b2Shape* b2Fixture::GetShape()
    244 {
    245 	return m_shape;
    246 }
    247 
    248 inline const b2Shape* b2Fixture::GetShape() const
    249 {
    250 	return m_shape;
    251 }
    252 
    253 inline bool b2Fixture::IsSensor() const
    254 {
    255 	return m_isSensor;
    256 }
    257 
    258 inline const b2Filter& b2Fixture::GetFilterData() const
    259 {
    260 	return m_filter;
    261 }
    262 
    263 inline void* b2Fixture::GetUserData() const
    264 {
    265 	return m_userData;
    266 }
    267 
    268 inline void b2Fixture::SetUserData(void* data)
    269 {
    270 	m_userData = data;
    271 }
    272 
    273 inline b2Body* b2Fixture::GetBody()
    274 {
    275 	return m_body;
    276 }
    277 
    278 inline const b2Body* b2Fixture::GetBody() const
    279 {
    280 	return m_body;
    281 }
    282 
    283 inline b2Fixture* b2Fixture::GetNext()
    284 {
    285 	return m_next;
    286 }
    287 
    288 inline const b2Fixture* b2Fixture::GetNext() const
    289 {
    290 	return m_next;
    291 }
    292 
    293 inline void b2Fixture::SetDensity(float32 density)
    294 {
    295 	b2Assert(b2IsValid(density) && density >= 0.0f);
    296 	m_density = density;
    297 }
    298 
    299 inline float32 b2Fixture::GetDensity() const
    300 {
    301 	return m_density;
    302 }
    303 
    304 inline float32 b2Fixture::GetFriction() const
    305 {
    306 	return m_friction;
    307 }
    308 
    309 inline void b2Fixture::SetFriction(float32 friction)
    310 {
    311 	m_friction = friction;
    312 }
    313 
    314 inline float32 b2Fixture::GetRestitution() const
    315 {
    316 	return m_restitution;
    317 }
    318 
    319 inline void b2Fixture::SetRestitution(float32 restitution)
    320 {
    321 	m_restitution = restitution;
    322 }
    323 
    324 inline bool b2Fixture::TestPoint(const b2Vec2& p) const
    325 {
    326 	return m_shape->TestPoint(m_body->GetTransform(), p);
    327 }
    328 
    329 inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const
    330 {
    331 	return m_shape->RayCast(output, input, m_body->GetTransform(), childIndex);
    332 }
    333 
    334 inline void b2Fixture::GetMassData(b2MassData* massData) const
    335 {
    336 	m_shape->ComputeMass(massData, m_density);
    337 }
    338 
    339 inline const b2AABB& b2Fixture::GetAABB(int32 childIndex) const
    340 {
    341 	b2Assert(0 <= childIndex && childIndex < m_proxyCount);
    342 	return m_proxies[childIndex].aabb;
    343 }
    344 
    345 #endif
    346