346 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
		
		
			
		
	
	
			346 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
|  | /*
 | ||
|  | * 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 "Box2D/Dynamics/b2Body.h"
 | ||
|  | #include "Box2D/Collision/b2Collision.h"
 | ||
|  | #include "Box2D/Collision/Shapes/b2Shape.h"
 | ||
|  | 
 | ||
|  | 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 = nullptr; | ||
|  | 		userData = nullptr; | ||
|  | 		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 nullptr 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
 |