/* * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef B2_FIXTURE_H #define B2_FIXTURE_H #include #include #include class b2BlockAllocator; class b2Body; class b2BroadPhase; class b2Fixture; /// This holds contact filtering data. struct b2Filter { b2Filter() { categoryBits = 0x0001; maskBits = 0xFFFF; groupIndex = 0; } /// The collision category bits. Normally you would just set one bit. uint16 categoryBits; /// The collision mask bits. This states the categories that this /// shape would accept for collision. uint16 maskBits; /// Collision groups allow a certain group of objects to never collide (negative) /// or always collide (positive). Zero means no collision group. Non-zero group /// filtering always wins against the mask bits. int16 groupIndex; }; /// A fixture definition is used to create a fixture. This class defines an /// abstract fixture definition. You can reuse fixture definitions safely. struct b2FixtureDef { /// The constructor sets the default fixture definition values. b2FixtureDef() { shape = NULL; userData = NULL; friction = 0.2f; restitution = 0.0f; density = 0.0f; isSensor = false; } /// The shape, this must be set. The shape will be cloned, so you /// can create the shape on the stack. const b2Shape* shape; /// Use this to store application specific fixture data. void* userData; /// The friction coefficient, usually in the range [0,1]. float32 friction; /// The restitution (elasticity) usually in the range [0,1]. float32 restitution; /// The density, usually in kg/m^2. float32 density; /// A sensor shape collects contact information but never generates a collision /// response. bool isSensor; /// Contact filtering data. b2Filter filter; }; /// This proxy is used internally to connect fixtures to the broad-phase. struct b2FixtureProxy { b2AABB aabb; b2Fixture* fixture; int32 childIndex; int32 proxyId; }; /// A fixture is used to attach a shape to a body for collision detection. A fixture /// inherits its transform from its parent. Fixtures hold additional non-geometric data /// such as friction, collision filters, etc. /// Fixtures are created via b2Body::CreateFixture. /// @warning you cannot reuse fixtures. class b2Fixture { public: /// Get the type of the child shape. You can use this to down cast to the concrete shape. /// @return the shape type. b2Shape::Type GetType() const; /// Get the child shape. You can modify the child shape, however you should not change the /// number of vertices because this will crash some collision caching mechanisms. /// Manipulating the shape may lead to non-physical behavior. b2Shape* GetShape(); const b2Shape* GetShape() const; /// Set if this fixture is a sensor. void SetSensor(bool sensor); /// Is this fixture a sensor (non-solid)? /// @return the true if the shape is a sensor. bool IsSensor() const; /// Set the contact filtering data. This will not update contacts until the next time /// step when either parent body is active and awake. /// This automatically calls Refilter. void SetFilterData(const b2Filter& filter); /// Get the contact filtering data. const b2Filter& GetFilterData() const; /// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide. void Refilter(); /// Get the parent body of this fixture. This is NULL if the fixture is not attached. /// @return the parent body. b2Body* GetBody(); const b2Body* GetBody() const; /// Get the next fixture in the parent body's fixture list. /// @return the next shape. b2Fixture* GetNext(); const b2Fixture* GetNext() const; /// Get the user data that was assigned in the fixture definition. Use this to /// store your application specific data. void* GetUserData() const; /// Set the user data. Use this to store your application specific data. void SetUserData(void* data); /// Test a point for containment in this fixture. /// @param p a point in world coordinates. bool TestPoint(const b2Vec2& p) const; /// Cast a ray against this shape. /// @param output the ray-cast results. /// @param input the ray-cast input parameters. bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const; /// Get the mass data for this fixture. The mass data is based on the density and /// the shape. The rotational inertia is about the shape's origin. This operation /// may be expensive. void GetMassData(b2MassData* massData) const; /// Set the density of this fixture. This will _not_ automatically adjust the mass /// of the body. You must call b2Body::ResetMassData to update the body's mass. void SetDensity(float32 density); /// Get the density of this fixture. float32 GetDensity() const; /// Get the coefficient of friction. float32 GetFriction() const; /// Set the coefficient of friction. This will _not_ change the friction of /// existing contacts. void SetFriction(float32 friction); /// Get the coefficient of restitution. float32 GetRestitution() const; /// Set the coefficient of restitution. This will _not_ change the restitution of /// existing contacts. void SetRestitution(float32 restitution); /// Get the fixture's AABB. This AABB may be enlarge and/or stale. /// If you need a more accurate AABB, compute it using the shape and /// the body transform. const b2AABB& GetAABB(int32 childIndex) const; /// Dump this fixture to the log file. void Dump(int32 bodyIndex); protected: friend class b2Body; friend class b2World; friend class b2Contact; friend class b2ContactManager; b2Fixture(); // We need separation create/destroy functions from the constructor/destructor because // the destructor cannot access the allocator (no destructor arguments allowed by C++). void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def); void Destroy(b2BlockAllocator* allocator); // These support body activation/deactivation. void CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf); void DestroyProxies(b2BroadPhase* broadPhase); void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2); float32 m_density; b2Fixture* m_next; b2Body* m_body; b2Shape* m_shape; float32 m_friction; float32 m_restitution; b2FixtureProxy* m_proxies; int32 m_proxyCount; b2Filter m_filter; bool m_isSensor; void* m_userData; }; inline b2Shape::Type b2Fixture::GetType() const { return m_shape->GetType(); } inline b2Shape* b2Fixture::GetShape() { return m_shape; } inline const b2Shape* b2Fixture::GetShape() const { return m_shape; } inline bool b2Fixture::IsSensor() const { return m_isSensor; } inline const b2Filter& b2Fixture::GetFilterData() const { return m_filter; } inline void* b2Fixture::GetUserData() const { return m_userData; } inline void b2Fixture::SetUserData(void* data) { m_userData = data; } inline b2Body* b2Fixture::GetBody() { return m_body; } inline const b2Body* b2Fixture::GetBody() const { return m_body; } inline b2Fixture* b2Fixture::GetNext() { return m_next; } inline const b2Fixture* b2Fixture::GetNext() const { return m_next; } inline void b2Fixture::SetDensity(float32 density) { b2Assert(b2IsValid(density) && density >= 0.0f); m_density = density; } inline float32 b2Fixture::GetDensity() const { return m_density; } inline float32 b2Fixture::GetFriction() const { return m_friction; } inline void b2Fixture::SetFriction(float32 friction) { m_friction = friction; } inline float32 b2Fixture::GetRestitution() const { return m_restitution; } inline void b2Fixture::SetRestitution(float32 restitution) { m_restitution = restitution; } inline bool b2Fixture::TestPoint(const b2Vec2& p) const { return m_shape->TestPoint(m_body->GetTransform(), p); } inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const { return m_shape->RayCast(output, input, m_body->GetTransform(), childIndex); } inline void b2Fixture::GetMassData(b2MassData* massData) const { m_shape->ComputeMass(massData, m_density); } inline const b2AABB& b2Fixture::GetAABB(int32 childIndex) const { b2Assert(0 <= childIndex && childIndex < m_proxyCount); return m_proxies[childIndex].aabb; } #endif