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