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