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