1 /*
2 * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
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 "b2Body.h"
23 #include "b2Collision.h"
24 #include "b2Shape.h"
25 
26 class b2BlockAllocator;
27 class b2Body;
28 class b2BroadPhase;
29 
30 /// This holds contact filtering data.
31 struct b2Filter
32 {
33 	/// The collision category bits. Normally you would just set one bit.
34 	uint16 categoryBits;
35 
36 	/// The collision mask bits. This states the categories that this
37 	/// shape would accept for collision.
38 	uint16 maskBits;
39 
40 	/// Collision groups allow a certain group of objects to never collide (negative)
41 	/// or always collide (positive). Zero means no collision group. Non-zero group
42 	/// filtering always wins against the mask bits.
43 	int16 groupIndex;
44 };
45 
46 /// A fixture definition is used to create a fixture. This class defines an
47 /// abstract fixture definition. You can reuse fixture definitions safely.
48 struct b2FixtureDef
49 {
50 	/// The constructor sets the default fixture definition values.
b2FixtureDefb2FixtureDef51 	b2FixtureDef()
52 	{
53 		shape = NULL;
54 		userData = NULL;
55 		friction = 0.2f;
56 		restitution = 0.0f;
57 		density = 0.0f;
58 		filter.categoryBits = 0x0001;
59 		filter.maskBits = 0xFFFF;
60 		filter.groupIndex = 0;
61 		isSensor = false;
62 	}
63 
~b2FixtureDefb2FixtureDef64 	virtual ~b2FixtureDef() {}
65 
66 	/// The shape, this must be set. The shape will be cloned, so you
67 	/// can create the shape on the stack.
68 	const b2Shape* shape;
69 
70 	/// Use this to store application specific fixture data.
71 	void* userData;
72 
73 	/// The friction coefficient, usually in the range [0,1].
74 	float32 friction;
75 
76 	/// The restitution (elasticity) usually in the range [0,1].
77 	float32 restitution;
78 
79 	/// The density, usually in kg/m^2.
80 	float32 density;
81 
82 	/// A sensor shape collects contact information but never generates a collision
83 	/// response.
84 	bool isSensor;
85 
86 	/// Contact filtering data.
87 	b2Filter filter;
88 };
89 
90 
91 /// A fixture is used to attach a shape to a body for collision detection. A fixture
92 /// inherits its transform from its parent. Fixtures hold additional non-geometric data
93 /// such as friction, collision filters, etc.
94 /// Fixtures are created via b2Body::CreateFixture.
95 /// @warning you cannot reuse fixtures.
96 class b2Fixture
97 {
98 public:
99 	/// Get the type of the child shape. You can use this to down cast to the concrete shape.
100 	/// @return the shape type.
101 	b2Shape::Type GetType() const;
102 
103 	/// Get the child shape. You can modify the child shape, however you should not change the
104 	/// number of vertices because this will crash some collision caching mechanisms.
105 	/// Manipulating the shape may lead to non-physical behavior.
106 	b2Shape* GetShape();
107 	const b2Shape* GetShape() const;
108 
109 	/// Set if this fixture is a sensor.
110 	void SetSensor(bool sensor);
111 
112 	/// Is this fixture a sensor (non-solid)?
113 	/// @return the true if the shape is a sensor.
114 	bool IsSensor() const;
115 
116 	/// Set the contact filtering data. This will not update contacts until the next time
117 	/// step when either parent body is active and awake.
118 	void SetFilterData(const b2Filter& filter);
119 
120 	/// Get the contact filtering data.
121 	const b2Filter& GetFilterData() const;
122 
123 	/// Get the parent body of this fixture. This is NULL if the fixture is not attached.
124 	/// @return the parent body.
125 	b2Body* GetBody();
126 	const b2Body* GetBody() const;
127 
128 	/// Get the next fixture in the parent body's fixture list.
129 	/// @return the next shape.
130 	b2Fixture* GetNext();
131 	const b2Fixture* GetNext() const;
132 
133 	/// Get the user data that was assigned in the fixture definition. Use this to
134 	/// store your application specific data.
135 	void* GetUserData() const;
136 
137 	/// Set the user data. Use this to store your application specific data.
138 	void SetUserData(void* data);
139 
140 	/// Test a point for containment in this fixture.
141 	/// @param xf the shape world transform.
142 	/// @param p a point in world coordinates.
143 	bool TestPoint(const b2Vec2& p) const;
144 
145 	/// Cast a ray against this shape.
146 	/// @param output the ray-cast results.
147 	/// @param input the ray-cast input parameters.
148 	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
149 
150 	/// Get the mass data for this fixture. The mass data is based on the density and
151 	/// the shape. The rotational inertia is about the shape's origin. This operation
152 	/// may be expensive.
153 	void GetMassData(b2MassData* massData) const;
154 
155 	/// Set the density of this fixture. This will _not_ automatically adjust the mass
156 	/// of the body. You must call b2Body::ResetMassData to update the body's mass.
157 	void SetDensity(float32 density);
158 
159 	/// Get the density of this fixture.
160 	float32 GetDensity() const;
161 
162 	/// Get the coefficient of friction.
163 	float32 GetFriction() const;
164 
165 	/// Set the coefficient of friction.
166 	void SetFriction(float32 friction);
167 
168 	/// Get the coefficient of restitution.
169 	float32 GetRestitution() const;
170 
171 	/// Set the coefficient of restitution.
172 	void SetRestitution(float32 restitution);
173 
174 	/// Get the fixture's AABB. This AABB may be enlarge and/or stale.
175 	/// If you need a more accurate AABB, compute it using the shape and
176 	/// the body transform.
177 	const b2AABB& GetAABB() const;
178 
179 protected:
180 
181 	friend class b2Body;
182 	friend class b2World;
183 	friend class b2Contact;
184 	friend class b2ContactManager;
185 
186 	b2Fixture();
187 	~b2Fixture();
188 
189 	// We need separation create/destroy functions from the constructor/destructor because
190 	// the destructor cannot access the allocator (no destructor arguments allowed by C++).
191 	void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def);
192 	void Destroy(b2BlockAllocator* allocator);
193 
194 	// These support body activation/deactivation.
195 	void CreateProxy(b2BroadPhase* broadPhase, const b2Transform& xf);
196 	void DestroyProxy(b2BroadPhase* broadPhase);
197 
198 	void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2);
199 
200 	b2AABB m_aabb;
201 
202 	float32 m_density;
203 
204 	b2Fixture* m_next;
205 	b2Body* m_body;
206 
207 	b2Shape* m_shape;
208 
209 	float32 m_friction;
210 	float32 m_restitution;
211 
212 	int32 m_proxyId;
213 	b2Filter m_filter;
214 
215 	bool m_isSensor;
216 
217 	void* m_userData;
218 };
219 
GetType()220 inline b2Shape::Type b2Fixture::GetType() const
221 {
222 	return m_shape->GetType();
223 }
224 
GetShape()225 inline b2Shape* b2Fixture::GetShape()
226 {
227 	return m_shape;
228 }
229 
GetShape()230 inline const b2Shape* b2Fixture::GetShape() const
231 {
232 	return m_shape;
233 }
234 
IsSensor()235 inline bool b2Fixture::IsSensor() const
236 {
237 	return m_isSensor;
238 }
239 
GetFilterData()240 inline const b2Filter& b2Fixture::GetFilterData() const
241 {
242 	return m_filter;
243 }
244 
GetUserData()245 inline void* b2Fixture::GetUserData() const
246 {
247 	return m_userData;
248 }
249 
SetUserData(void * data)250 inline void b2Fixture::SetUserData(void* data)
251 {
252 	m_userData = data;
253 }
254 
GetBody()255 inline b2Body* b2Fixture::GetBody()
256 {
257 	return m_body;
258 }
259 
GetBody()260 inline const b2Body* b2Fixture::GetBody() const
261 {
262 	return m_body;
263 }
264 
GetNext()265 inline b2Fixture* b2Fixture::GetNext()
266 {
267 	return m_next;
268 }
269 
GetNext()270 inline const b2Fixture* b2Fixture::GetNext() const
271 {
272 	return m_next;
273 }
274 
SetDensity(float32 density)275 inline void b2Fixture::SetDensity(float32 density)
276 {
277 	b2Assert(b2IsValid(density) && density >= 0.0f);
278 	m_density = density;
279 }
280 
GetDensity()281 inline float32 b2Fixture::GetDensity() const
282 {
283 	return m_density;
284 }
285 
GetFriction()286 inline float32 b2Fixture::GetFriction() const
287 {
288 	return m_friction;
289 }
290 
SetFriction(float32 friction)291 inline void b2Fixture::SetFriction(float32 friction)
292 {
293 	m_friction = friction;
294 }
295 
GetRestitution()296 inline float32 b2Fixture::GetRestitution() const
297 {
298 	return m_restitution;
299 }
300 
SetRestitution(float32 restitution)301 inline void b2Fixture::SetRestitution(float32 restitution)
302 {
303 	m_restitution = restitution;
304 }
305 
TestPoint(const b2Vec2 & p)306 inline bool b2Fixture::TestPoint(const b2Vec2& p) const
307 {
308 	return m_shape->TestPoint(m_body->GetTransform(), p);
309 }
310 
RayCast(b2RayCastOutput * output,const b2RayCastInput & input)311 inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const
312 {
313 	return m_shape->RayCast(output, input, m_body->GetTransform());
314 }
315 
GetMassData(b2MassData * massData)316 inline void b2Fixture::GetMassData(b2MassData* massData) const
317 {
318 	m_shape->ComputeMass(massData, m_density);
319 }
320 
GetAABB()321 inline const b2AABB& b2Fixture::GetAABB() const
322 {
323 	return m_aabb;
324 }
325 
326 #endif
327