first commit
[blok] / Box2D / Source / Collision / Shapes / b2Shape.h
1 /*
2 * Copyright (c) 2006-2007 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_SHAPE_H
20 #define B2_SHAPE_H
21
22 #include "../../Common/b2Math.h"
23 #include "../b2Collision.h"
24
25 class b2BlockAllocator;
26 class b2Body;
27 class b2BroadPhase;
28
29 /// This holds the mass data computed for a shape.
30 struct b2MassData
31 {
32         /// The mass of the shape, usually in kilograms.
33         float32 mass;
34
35         /// The position of the shape's centroid relative to the shape's origin.
36         b2Vec2 center;
37
38         /// The rotational inertia of the shape.
39         float32 I;
40 };
41
42 /// This holds contact filtering data.
43 struct b2FilterData
44 {
45         /// The collision category bits. Normally you would just set one bit.
46         uint16 categoryBits;
47
48         /// The collision mask bits. This states the categories that this
49         /// shape would accept for collision.
50         uint16 maskBits;
51
52         /// Collision groups allow a certain group of objects to never collide (negative)
53         /// or always collide (positive). Zero means no collision group. Non-zero group
54         /// filtering always wins against the mask bits.
55         int16 groupIndex;
56 };
57
58 /// The various collision shape types supported by Box2D.
59 enum b2ShapeType
60 {
61         e_unknownShape = -1,
62         e_circleShape,
63         e_polygonShape,
64         e_shapeTypeCount,
65 };
66
67 /// A shape definition is used to construct a shape. This class defines an
68 /// abstract shape definition. You can reuse shape definitions safely.
69 struct b2ShapeDef
70 {
71         /// The constructor sets the default shape definition values.
72         b2ShapeDef()
73         {
74                 type = e_unknownShape;
75                 userData = NULL;
76                 friction = 0.2f;
77                 restitution = 0.0f;
78                 density = 0.0f;
79                 filter.categoryBits = 0x0001;
80                 filter.maskBits = 0xFFFF;
81                 filter.groupIndex = 0;
82                 isSensor = false;
83         }
84
85         virtual ~b2ShapeDef() {}
86
87         /// Holds the shape type for down-casting.
88         b2ShapeType type;
89
90         /// Use this to store application specify shape data.
91         void* userData;
92
93         /// The shape's friction coefficient, usually in the range [0,1].
94         float32 friction;
95
96         /// The shape's restitution (elasticity) usually in the range [0,1].
97         float32 restitution;
98
99         /// The shape's density, usually in kg/m^2.
100         float32 density;
101
102         /// A sensor shape collects contact information but never generates a collision
103         /// response.
104         bool isSensor;
105
106         /// Contact filtering data.
107         b2FilterData filter;
108 };
109
110 /// A shape is used for collision detection. Shapes are created in b2World.
111 /// You can use shape for collision detection before they are attached to the world.
112 /// @warning you cannot reuse shapes.
113 class b2Shape
114 {
115 public:
116         /// Get the type of this shape. You can use this to down cast to the concrete shape.
117         /// @return the shape type.
118         b2ShapeType GetType() const;
119
120         /// Is this shape a sensor (non-solid)?
121         /// @return the true if the shape is a sensor.
122         bool IsSensor() const;
123
124         /// Set the contact filtering data. You must call b2World::Refilter to correct
125         /// existing contacts/non-contacts.
126         void SetFilterData(const b2FilterData& filter);
127
128         /// Get the contact filtering data.
129         const b2FilterData& GetFilterData() const;
130
131         /// Get the parent body of this shape. This is NULL if the shape is not attached.
132         /// @return the parent body.
133         b2Body* GetBody();
134
135         /// Get the next shape in the parent body's shape list.
136         /// @return the next shape.
137         b2Shape* GetNext();
138
139         /// Get the user data that was assigned in the shape definition. Use this to
140         /// store your application specific data.
141         void* GetUserData();
142
143         /// Set the user data. Use this to store your application specific data.
144         void SetUserData(void* data);
145
146         /// Test a point for containment in this shape. This only works for convex shapes.
147         /// @param xf the shape world transform.
148         /// @param p a point in world coordinates.
149         virtual bool TestPoint(const b2XForm& xf, const b2Vec2& p) const = 0;
150
151         /// Perform a ray cast against this shape.
152         /// @param xf the shape world transform.
153         /// @param lambda returns the hit fraction. You can use this to compute the contact point
154         /// p = (1 - lambda) * segment.p1 + lambda * segment.p2.
155         /// @param normal returns the normal at the contact point. If there is no intersection, the normal
156         /// is not set.
157         /// @param segment defines the begin and end point of the ray cast.
158         /// @param maxLambda a number typically in the range [0,1].
159         /// @return true if there was an intersection.
160         virtual bool TestSegment(       const b2XForm& xf,
161                                                                 float32* lambda,
162                                                                 b2Vec2* normal,
163                                                                 const b2Segment& segment,
164                                                                 float32 maxLambda) const = 0;
165
166         /// Given a transform, compute the associated axis aligned bounding box for this shape.
167         /// @param aabb returns the axis aligned box.
168         /// @param xf the world transform of the shape.
169         virtual void ComputeAABB(b2AABB* aabb, const b2XForm& xf) const = 0;
170
171         /// Given two transforms, compute the associated swept axis aligned bounding box for this shape.
172         /// @param aabb returns the axis aligned box.
173         /// @param xf1 the starting shape world transform.
174         /// @param xf2 the ending shape world transform.
175         virtual void ComputeSweptAABB(  b2AABB* aabb,
176                                                                         const b2XForm& xf1,
177                                                                         const b2XForm& xf2) const = 0;
178
179         /// Compute the mass properties of this shape using its dimensions and density.
180         /// The inertia tensor is computed about the local origin, not the centroid.
181         /// @param massData returns the mass data for this shape.
182         virtual void ComputeMass(b2MassData* massData) const = 0;
183
184         /// Get the maximum radius about the parent body's center of mass.
185         float32 GetSweepRadius() const;
186
187         /// Get the coefficient of friction.
188         float32 GetFriction() const;
189
190         /// Get the coefficient of restitution.
191         float32 GetRestitution() const;
192
193 protected:
194
195         friend class b2Body;
196         friend class b2World;
197
198         static b2Shape* Create(const b2ShapeDef* def, b2BlockAllocator* allocator);
199         static void Destroy(b2Shape* shape, b2BlockAllocator* allocator);
200
201         b2Shape(const b2ShapeDef* def);
202         virtual ~b2Shape();
203
204         void CreateProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
205         void DestroyProxy(b2BroadPhase* broadPhase);
206         bool Synchronize(b2BroadPhase* broadPhase, const b2XForm& xf1, const b2XForm& xf2);
207         void RefilterProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
208
209         virtual void UpdateSweepRadius(const b2Vec2& center) = 0;
210
211         b2ShapeType m_type;
212         b2Shape* m_next;
213         b2Body* m_body;
214
215         // Sweep radius relative to the parent body's center of mass.
216         float32 m_sweepRadius;
217
218         float32 m_density;
219         float32 m_friction;
220         float32 m_restitution;
221
222         uint16 m_proxyId;
223         b2FilterData m_filter;
224
225         bool m_isSensor;
226
227         void* m_userData;
228 };
229
230 inline b2ShapeType b2Shape::GetType() const
231 {
232         return m_type;
233 }
234
235 inline bool b2Shape::IsSensor() const
236 {
237         return m_isSensor;
238 }
239
240 inline void b2Shape::SetFilterData(const b2FilterData& filter)
241 {
242         m_filter = filter;
243 }
244
245 inline const b2FilterData& b2Shape::GetFilterData() const
246 {
247         return m_filter;
248 }
249
250 inline void* b2Shape::GetUserData()
251 {
252         return m_userData;
253 }
254
255 inline void b2Shape::SetUserData(void* data)
256 {
257         m_userData = data;
258 }
259
260 inline b2Body* b2Shape::GetBody()
261 {
262         return m_body;
263 }
264
265 inline b2Shape* b2Shape::GetNext()
266 {
267         return m_next;
268 }
269
270 inline float32 b2Shape::GetSweepRadius() const
271 {
272         return m_sweepRadius;
273 }
274
275 inline float32 b2Shape::GetFriction() const
276 {
277         return m_friction;
278 }
279
280 inline float32 b2Shape::GetRestitution() const
281 {
282         return m_restitution;
283 }
284
285 #endif