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.
b2ShapeDefb2ShapeDef72 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
~b2ShapeDefb2ShapeDef85 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 float32 m_density;
194 float32 m_friction;
195 float32 m_restitution;
196 bool m_isSensor;
197
198 protected:
199
200 friend class b2Body;
201 friend class b2World;
202
203 static b2Shape* Create(const b2ShapeDef* def, b2BlockAllocator* allocator);
204 static void Destroy(b2Shape* shape, b2BlockAllocator* allocator);
205
206 b2Shape(const b2ShapeDef* def);
207 virtual ~b2Shape();
208
209 void CreateProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
210 void DestroyProxy(b2BroadPhase* broadPhase);
211 bool Synchronize(b2BroadPhase* broadPhase, const b2XForm& xf1, const b2XForm& xf2);
212 void RefilterProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
213
214 virtual void UpdateSweepRadius(const b2Vec2& center) = 0;
215
216 b2ShapeType m_type;
217 b2Shape* m_next;
218 b2Body* m_body;
219
220 // Sweep radius relative to the parent body's center of mass.
221 float32 m_sweepRadius;
222
223 uint16 m_proxyId;
224 b2FilterData m_filter;
225
226
227
228 void* m_userData;
229 };
230
GetType()231 inline b2ShapeType b2Shape::GetType() const
232 {
233 return m_type;
234 }
235
IsSensor()236 inline bool b2Shape::IsSensor() const
237 {
238 return m_isSensor;
239 }
240
SetFilterData(const b2FilterData & filter)241 inline void b2Shape::SetFilterData(const b2FilterData& filter)
242 {
243 m_filter = filter;
244 }
245
GetFilterData()246 inline const b2FilterData& b2Shape::GetFilterData() const
247 {
248 return m_filter;
249 }
250
GetUserData()251 inline void* b2Shape::GetUserData()
252 {
253 return m_userData;
254 }
255
SetUserData(void * data)256 inline void b2Shape::SetUserData(void* data)
257 {
258 m_userData = data;
259 }
260
GetBody()261 inline b2Body* b2Shape::GetBody()
262 {
263 return m_body;
264 }
265
GetNext()266 inline b2Shape* b2Shape::GetNext()
267 {
268 return m_next;
269 }
270
GetSweepRadius()271 inline float32 b2Shape::GetSweepRadius() const
272 {
273 return m_sweepRadius;
274 }
275
GetFriction()276 inline float32 b2Shape::GetFriction() const
277 {
278 return m_friction;
279 }
280
GetRestitution()281 inline float32 b2Shape::GetRestitution() const
282 {
283 return m_restitution;
284 }
285
286 #endif
287