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