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 | { |
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. |
56 | struct 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. |
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 | class b2Fixture |
108 | { |
109 | public: |
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 | |
198 | protected: |
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 | |
238 | inline b2Shape::Type b2Fixture::GetType() const |
239 | { |
240 | return m_shape->GetType(); |
241 | } |
242 | |
243 | inline b2Shape* b2Fixture::GetShape() |
244 | { |
245 | return m_shape; |
246 | } |
247 | |
248 | inline const b2Shape* b2Fixture::GetShape() const |
249 | { |
250 | return m_shape; |
251 | } |
252 | |
253 | inline bool b2Fixture::IsSensor() const |
254 | { |
255 | return m_isSensor; |
256 | } |
257 | |
258 | inline const b2Filter& b2Fixture::GetFilterData() const |
259 | { |
260 | return m_filter; |
261 | } |
262 | |
263 | inline void* b2Fixture::GetUserData() const |
264 | { |
265 | return m_userData; |
266 | } |
267 | |
268 | inline void b2Fixture::SetUserData(void* data) |
269 | { |
270 | m_userData = data; |
271 | } |
272 | |
273 | inline b2Body* b2Fixture::GetBody() |
274 | { |
275 | return m_body; |
276 | } |
277 | |
278 | inline const b2Body* b2Fixture::GetBody() const |
279 | { |
280 | return m_body; |
281 | } |
282 | |
283 | inline b2Fixture* b2Fixture::GetNext() |
284 | { |
285 | return m_next; |
286 | } |
287 | |
288 | inline const b2Fixture* b2Fixture::GetNext() const |
289 | { |
290 | return m_next; |
291 | } |
292 | |
293 | inline void b2Fixture::SetDensity(float32 density) |
294 | { |
295 | b2Assert(b2IsValid(density) && density >= 0.0f); |
296 | m_density = density; |
297 | } |
298 | |
299 | inline float32 b2Fixture::GetDensity() const |
300 | { |
301 | return m_density; |
302 | } |
303 | |
304 | inline float32 b2Fixture::GetFriction() const |
305 | { |
306 | return m_friction; |
307 | } |
308 | |
309 | inline void b2Fixture::SetFriction(float32 friction) |
310 | { |
311 | m_friction = friction; |
312 | } |
313 | |
314 | inline float32 b2Fixture::GetRestitution() const |
315 | { |
316 | return m_restitution; |
317 | } |
318 | |
319 | inline void b2Fixture::SetRestitution(float32 restitution) |
320 | { |
321 | m_restitution = restitution; |
322 | } |
323 | |
324 | inline bool b2Fixture::TestPoint(const b2Vec2& p) const |
325 | { |
326 | return m_shape->TestPoint(m_body->GetTransform(), p); |
327 | } |
328 | |
329 | inline 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 | |
334 | inline void b2Fixture::GetMassData(b2MassData* massData) const |
335 | { |
336 | m_shape->ComputeMass(massData, m_density); |
337 | } |
338 | |
339 | inline 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 | |