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