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