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 {
b2Filterb2Filter34 	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.
b2FixtureDefb2FixtureDef59 	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 // emscripten - b2Fixture: make constructor public
108 class b2Fixture
109 {
110 public:
111 	/// Get the type of the child shape. You can use this to down cast to the concrete shape.
112 	/// @return the shape type.
113 	b2Shape::Type GetType() const;
114 
115 	/// Get the child shape. You can modify the child shape, however you should not change the
116 	/// number of vertices because this will crash some collision caching mechanisms.
117 	/// Manipulating the shape may lead to non-physical behavior.
118 	b2Shape* GetShape();
119 	const b2Shape* GetShape() const;
120 
121 	/// Set if this fixture is a sensor.
122 	void SetSensor(bool sensor);
123 
124 	/// Is this fixture a sensor (non-solid)?
125 	/// @return the true if the shape is a sensor.
126 	bool IsSensor() const;
127 
128 	/// Set the contact filtering data. This will not update contacts until the next time
129 	/// step when either parent body is active and awake.
130 	/// This automatically calls Refilter.
131 	void SetFilterData(const b2Filter& filter);
132 
133 	/// Get the contact filtering data.
134 	const b2Filter& GetFilterData() const;
135 
136 	/// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
137 	void Refilter();
138 
139 	/// Get the parent body of this fixture. This is NULL if the fixture is not attached.
140 	/// @return the parent body.
141 	b2Body* GetBody();
142 	const b2Body* GetBody() const;
143 
144 	/// Get the next fixture in the parent body's fixture list.
145 	/// @return the next shape.
146 	b2Fixture* GetNext();
147 	const b2Fixture* GetNext() const;
148 
149 	/// Get the user data that was assigned in the fixture definition. Use this to
150 	/// store your application specific data.
151 	void* GetUserData() const;
152 
153 	/// Set the user data. Use this to store your application specific data.
154 	void SetUserData(void* data);
155 
156 	/// Test a point for containment in this fixture.
157 	/// @param p a point in world coordinates.
158 	bool TestPoint(const b2Vec2& p) const;
159 
160 	/// Cast a ray against this shape.
161 	/// @param output the ray-cast results.
162 	/// @param input the ray-cast input parameters.
163 	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const;
164 
165 	/// Get the mass data for this fixture. The mass data is based on the density and
166 	/// the shape. The rotational inertia is about the shape's origin. This operation
167 	/// may be expensive.
168 	void GetMassData(b2MassData* massData) const;
169 
170 	/// Set the density of this fixture. This will _not_ automatically adjust the mass
171 	/// of the body. You must call b2Body::ResetMassData to update the body's mass.
172 	void SetDensity(float32 density);
173 
174 	/// Get the density of this fixture.
175 	float32 GetDensity() const;
176 
177 	/// Get the coefficient of friction.
178 	float32 GetFriction() const;
179 
180 	/// Set the coefficient of friction. This will _not_ change the friction of
181 	/// existing contacts.
182 	void SetFriction(float32 friction);
183 
184 	/// Get the coefficient of restitution.
185 	float32 GetRestitution() const;
186 
187 	/// Set the coefficient of restitution. This will _not_ change the restitution of
188 	/// existing contacts.
189 	void SetRestitution(float32 restitution);
190 
191 	/// Get the fixture's AABB. This AABB may be enlarge and/or stale.
192 	/// If you need a more accurate AABB, compute it using the shape and
193 	/// the body transform.
194 	const b2AABB& GetAABB(int32 childIndex) const;
195 
196 	/// Dump this fixture to the log file.
197 	void Dump(int32 bodyIndex);
198 
199 protected:
200 
201 	friend class b2Body;
202 	friend class b2World;
203 	friend class b2Contact;
204 	friend class b2ContactManager;
205 
206 public:
207 	b2Fixture();
208 
209 protected:
210 	// We need separation create/destroy functions from the constructor/destructor because
211 	// the destructor cannot access the allocator (no destructor arguments allowed by C++).
212 	void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def);
213 	void Destroy(b2BlockAllocator* allocator);
214 
215 	// These support body activation/deactivation.
216 	void CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf);
217 	void DestroyProxies(b2BroadPhase* broadPhase);
218 
219 	void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2);
220 
221 	float32 m_density;
222 
223 	b2Fixture* m_next;
224 	b2Body* m_body;
225 
226 	b2Shape* m_shape;
227 
228 	float32 m_friction;
229 	float32 m_restitution;
230 
231 	b2FixtureProxy* m_proxies;
232 	int32 m_proxyCount;
233 
234 	b2Filter m_filter;
235 
236 	bool m_isSensor;
237 
238 	void* m_userData;
239 };
240 
GetType()241 inline b2Shape::Type b2Fixture::GetType() const
242 {
243 	return m_shape->GetType();
244 }
245 
GetShape()246 inline b2Shape* b2Fixture::GetShape()
247 {
248 	return m_shape;
249 }
250 
GetShape()251 inline const b2Shape* b2Fixture::GetShape() const
252 {
253 	return m_shape;
254 }
255 
IsSensor()256 inline bool b2Fixture::IsSensor() const
257 {
258 	return m_isSensor;
259 }
260 
GetFilterData()261 inline const b2Filter& b2Fixture::GetFilterData() const
262 {
263 	return m_filter;
264 }
265 
GetUserData()266 inline void* b2Fixture::GetUserData() const
267 {
268 	return m_userData;
269 }
270 
SetUserData(void * data)271 inline void b2Fixture::SetUserData(void* data)
272 {
273 	m_userData = data;
274 }
275 
GetBody()276 inline b2Body* b2Fixture::GetBody()
277 {
278 	return m_body;
279 }
280 
GetBody()281 inline const b2Body* b2Fixture::GetBody() const
282 {
283 	return m_body;
284 }
285 
GetNext()286 inline b2Fixture* b2Fixture::GetNext()
287 {
288 	return m_next;
289 }
290 
GetNext()291 inline const b2Fixture* b2Fixture::GetNext() const
292 {
293 	return m_next;
294 }
295 
SetDensity(float32 density)296 inline void b2Fixture::SetDensity(float32 density)
297 {
298 	b2Assert(b2IsValid(density) && density >= 0.0f);
299 	m_density = density;
300 }
301 
GetDensity()302 inline float32 b2Fixture::GetDensity() const
303 {
304 	return m_density;
305 }
306 
GetFriction()307 inline float32 b2Fixture::GetFriction() const
308 {
309 	return m_friction;
310 }
311 
SetFriction(float32 friction)312 inline void b2Fixture::SetFriction(float32 friction)
313 {
314 	m_friction = friction;
315 }
316 
GetRestitution()317 inline float32 b2Fixture::GetRestitution() const
318 {
319 	return m_restitution;
320 }
321 
SetRestitution(float32 restitution)322 inline void b2Fixture::SetRestitution(float32 restitution)
323 {
324 	m_restitution = restitution;
325 }
326 
TestPoint(const b2Vec2 & p)327 inline bool b2Fixture::TestPoint(const b2Vec2& p) const
328 {
329 	return m_shape->TestPoint(m_body->GetTransform(), p);
330 }
331 
RayCast(b2RayCastOutput * output,const b2RayCastInput & input,int32 childIndex)332 inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const
333 {
334 	return m_shape->RayCast(output, input, m_body->GetTransform(), childIndex);
335 }
336 
GetMassData(b2MassData * massData)337 inline void b2Fixture::GetMassData(b2MassData* massData) const
338 {
339 	m_shape->ComputeMass(massData, m_density);
340 }
341 
GetAABB(int32 childIndex)342 inline const b2AABB& b2Fixture::GetAABB(int32 childIndex) const
343 {
344 	b2Assert(0 <= childIndex && childIndex < m_proxyCount);
345 	return m_proxies[childIndex].aabb;
346 }
347 
348 #endif
349