| 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 | |