File indexing completed on 2025-08-03 03:50:01

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