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