File indexing completed on 2024-05-19 14:56:32

0001 /*
0002 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
0003 *
0004 * This software is provided 'as-is', without any express or implied
0005 * warranty.  In no event will the authors be held liable for any damages
0006 * arising from the use of this software.
0007 * Permission is granted to anyone to use this software for any purpose,
0008 * including commercial applications, and to alter it and redistribute it
0009 * freely, subject to the following restrictions:
0010 * 1. The origin of this software must not be misrepresented; you must not
0011 * claim that you wrote the original software. If you use this software
0012 * in a product, an acknowledgment in the product documentation would be
0013 * appreciated but is not required.
0014 * 2. Altered source versions must be plainly marked as such, and must not be
0015 * misrepresented as being the original software.
0016 * 3. This notice may not be removed or altered from any source distribution.
0017 */
0018 
0019 #ifndef B2_FIXTURE_H
0020 #define B2_FIXTURE_H
0021 
0022 #include <Box2D/Dynamics/b2Body.h>
0023 #include <Box2D/Collision/b2Collision.h>
0024 #include <Box2D/Collision/Shapes/b2Shape.h>
0025 
0026 class b2BlockAllocator;
0027 class b2Body;
0028 class b2BroadPhase;
0029 class b2Fixture;
0030 
0031 /// This holds contact filtering data.
0032 struct b2Filter
0033 {
0034     b2Filter()
0035     {
0036         categoryBits = 0x0001;
0037         maskBits = 0xFFFF;
0038         groupIndex = 0;
0039     }
0040 
0041     /// The collision category bits. Normally you would just set one bit.
0042     uint16 categoryBits;
0043 
0044     /// The collision mask bits. This states the categories that this
0045     /// shape would accept for collision.
0046     uint16 maskBits;
0047 
0048     /// Collision groups allow a certain group of objects to never collide (negative)
0049     /// or always collide (positive). Zero means no collision group. Non-zero group
0050     /// filtering always wins against the mask bits.
0051     int16 groupIndex;
0052 };
0053 
0054 /// A fixture definition is used to create a fixture. This class defines an
0055 /// abstract fixture definition. You can reuse fixture definitions safely.
0056 struct b2FixtureDef
0057 {
0058     /// The constructor sets the default fixture definition values.
0059     b2FixtureDef()
0060     {
0061         shape = NULL;
0062         userData = NULL;
0063         friction = 0.2f;
0064         restitution = 0.0f;
0065         density = 0.0f;
0066         isSensor = false;
0067     }
0068 
0069     /// The shape, this must be set. The shape will be cloned, so you
0070     /// can create the shape on the stack.
0071     const b2Shape* shape;
0072 
0073     /// Use this to store application specific fixture data.
0074     void* userData;
0075 
0076     /// The friction coefficient, usually in the range [0,1].
0077     float32 friction;
0078 
0079     /// The restitution (elasticity) usually in the range [0,1].
0080     float32 restitution;
0081 
0082     /// The density, usually in kg/m^2.
0083     float32 density;
0084 
0085     /// A sensor shape collects contact information but never generates a collision
0086     /// response.
0087     bool isSensor;
0088 
0089     /// Contact filtering data.
0090     b2Filter filter;
0091 };
0092 
0093 /// This proxy is used internally to connect fixtures to the broad-phase.
0094 struct b2FixtureProxy
0095 {
0096     b2AABB aabb;
0097     b2Fixture* fixture;
0098     int32 childIndex;
0099     int32 proxyId;
0100 };
0101 
0102 /// A fixture is used to attach a shape to a body for collision detection. A fixture
0103 /// inherits its transform from its parent. Fixtures hold additional non-geometric data
0104 /// such as friction, collision filters, etc.
0105 /// Fixtures are created via b2Body::CreateFixture.
0106 /// @warning you cannot reuse fixtures.
0107 class b2Fixture
0108 {
0109 public:
0110     /// Get the type of the child shape. You can use this to down cast to the concrete shape.
0111     /// @return the shape type.
0112     b2Shape::Type GetType() const;
0113 
0114     /// Get the child shape. You can modify the child shape, however you should not change the
0115     /// number of vertices because this will crash some collision caching mechanisms.
0116     /// Manipulating the shape may lead to non-physical behavior.
0117     b2Shape* GetShape();
0118     const b2Shape* GetShape() const;
0119 
0120     /// Set if this fixture is a sensor.
0121     void SetSensor(bool sensor);
0122 
0123     /// Is this fixture a sensor (non-solid)?
0124     /// @return the true if the shape is a sensor.
0125     bool IsSensor() const;
0126 
0127     /// Set the contact filtering data. This will not update contacts until the next time
0128     /// step when either parent body is active and awake.
0129     /// This automatically calls Refilter.
0130     void SetFilterData(const b2Filter& filter);
0131 
0132     /// Get the contact filtering data.
0133     const b2Filter& GetFilterData() const;
0134 
0135     /// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
0136     void Refilter();
0137 
0138     /// Get the parent body of this fixture. This is NULL if the fixture is not attached.
0139     /// @return the parent body.
0140     b2Body* GetBody();
0141     const b2Body* GetBody() const;
0142 
0143     /// Get the next fixture in the parent body's fixture list.
0144     /// @return the next shape.
0145     b2Fixture* GetNext();
0146     const b2Fixture* GetNext() const;
0147 
0148     /// Get the user data that was assigned in the fixture definition. Use this to
0149     /// store your application specific data.
0150     void* GetUserData() const;
0151 
0152     /// Set the user data. Use this to store your application specific data.
0153     void SetUserData(void* data);
0154 
0155     /// Test a point for containment in this fixture.
0156     /// @param p a point in world coordinates.
0157     bool TestPoint(const b2Vec2& p) const;
0158 
0159     /// Cast a ray against this shape.
0160     /// @param output the ray-cast results.
0161     /// @param input the ray-cast input parameters.
0162     bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const;
0163 
0164     /// Get the mass data for this fixture. The mass data is based on the density and
0165     /// the shape. The rotational inertia is about the shape's origin. This operation
0166     /// may be expensive.
0167     void GetMassData(b2MassData* massData) const;
0168 
0169     /// Set the density of this fixture. This will _not_ automatically adjust the mass
0170     /// of the body. You must call b2Body::ResetMassData to update the body's mass.
0171     void SetDensity(float32 density);
0172 
0173     /// Get the density of this fixture.
0174     float32 GetDensity() const;
0175 
0176     /// Get the coefficient of friction.
0177     float32 GetFriction() const;
0178 
0179     /// Set the coefficient of friction. This will _not_ change the friction of
0180     /// existing contacts.
0181     void SetFriction(float32 friction);
0182 
0183     /// Get the coefficient of restitution.
0184     float32 GetRestitution() const;
0185 
0186     /// Set the coefficient of restitution. This will _not_ change the restitution of
0187     /// existing contacts.
0188     void SetRestitution(float32 restitution);
0189 
0190     /// Get the fixture's AABB. This AABB may be enlarge and/or stale.
0191     /// If you need a more accurate AABB, compute it using the shape and
0192     /// the body transform.
0193     const b2AABB& GetAABB(int32 childIndex) const;
0194 
0195     /// Dump this fixture to the log file.
0196     void Dump(int32 bodyIndex);
0197 
0198 protected:
0199 
0200     friend class b2Body;
0201     friend class b2World;
0202     friend class b2Contact;
0203     friend class b2ContactManager;
0204 
0205     b2Fixture();
0206 
0207     // We need separation create/destroy functions from the constructor/destructor because
0208     // the destructor cannot access the allocator (no destructor arguments allowed by C++).
0209     void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def);
0210     void Destroy(b2BlockAllocator* allocator);
0211 
0212     // These support body activation/deactivation.
0213     void CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf);
0214     void DestroyProxies(b2BroadPhase* broadPhase);
0215 
0216     void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2);
0217 
0218     float32 m_density;
0219 
0220     b2Fixture* m_next;
0221     b2Body* m_body;
0222 
0223     b2Shape* m_shape;
0224 
0225     float32 m_friction;
0226     float32 m_restitution;
0227 
0228     b2FixtureProxy* m_proxies;
0229     int32 m_proxyCount;
0230 
0231     b2Filter m_filter;
0232 
0233     bool m_isSensor;
0234 
0235     void* m_userData;
0236 };
0237 
0238 inline b2Shape::Type b2Fixture::GetType() const
0239 {
0240     return m_shape->GetType();
0241 }
0242 
0243 inline b2Shape* b2Fixture::GetShape()
0244 {
0245     return m_shape;
0246 }
0247 
0248 inline const b2Shape* b2Fixture::GetShape() const
0249 {
0250     return m_shape;
0251 }
0252 
0253 inline bool b2Fixture::IsSensor() const
0254 {
0255     return m_isSensor;
0256 }
0257 
0258 inline const b2Filter& b2Fixture::GetFilterData() const
0259 {
0260     return m_filter;
0261 }
0262 
0263 inline void* b2Fixture::GetUserData() const
0264 {
0265     return m_userData;
0266 }
0267 
0268 inline void b2Fixture::SetUserData(void* data)
0269 {
0270     m_userData = data;
0271 }
0272 
0273 inline b2Body* b2Fixture::GetBody()
0274 {
0275     return m_body;
0276 }
0277 
0278 inline const b2Body* b2Fixture::GetBody() const
0279 {
0280     return m_body;
0281 }
0282 
0283 inline b2Fixture* b2Fixture::GetNext()
0284 {
0285     return m_next;
0286 }
0287 
0288 inline const b2Fixture* b2Fixture::GetNext() const
0289 {
0290     return m_next;
0291 }
0292 
0293 inline void b2Fixture::SetDensity(float32 density)
0294 {
0295     b2Assert(b2IsValid(density) && density >= 0.0f);
0296     m_density = density;
0297 }
0298 
0299 inline float32 b2Fixture::GetDensity() const
0300 {
0301     return m_density;
0302 }
0303 
0304 inline float32 b2Fixture::GetFriction() const
0305 {
0306     return m_friction;
0307 }
0308 
0309 inline void b2Fixture::SetFriction(float32 friction)
0310 {
0311     m_friction = friction;
0312 }
0313 
0314 inline float32 b2Fixture::GetRestitution() const
0315 {
0316     return m_restitution;
0317 }
0318 
0319 inline void b2Fixture::SetRestitution(float32 restitution)
0320 {
0321     m_restitution = restitution;
0322 }
0323 
0324 inline bool b2Fixture::TestPoint(const b2Vec2& p) const
0325 {
0326     return m_shape->TestPoint(m_body->GetTransform(), p);
0327 }
0328 
0329 inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const
0330 {
0331     return m_shape->RayCast(output, input, m_body->GetTransform(), childIndex);
0332 }
0333 
0334 inline void b2Fixture::GetMassData(b2MassData* massData) const
0335 {
0336     m_shape->ComputeMass(massData, m_density);
0337 }
0338 
0339 inline const b2AABB& b2Fixture::GetAABB(int32 childIndex) const
0340 {
0341     b2Assert(0 <= childIndex && childIndex < m_proxyCount);
0342     return m_proxies[childIndex].aabb;
0343 }
0344 
0345 #endif