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 b2Body;
26 class b2BroadPhase;
27 
28 struct b2MassData
29 {
30 	float32 mass;
31 	b2Vec2 center;
32 	float32 I;
33 };
34 
35 enum b2ShapeType
36 {
37 	e_unknownShape = -1,
38 	e_circleShape,
39 	e_boxShape,
40 	e_polyShape,
41 	e_meshShape,
42 	e_shapeTypeCount,
43 };
44 
45 struct b2ShapeDef
46 {
b2ShapeDefb2ShapeDef47 	b2ShapeDef()
48 	{
49 		type = e_unknownShape;
50 		userData = NULL;
51 		localPosition.Set(0.0f, 0.0f);
52 		localRotation = 0.0f;
53 		friction = 0.2f;
54 		restitution = 0.0f;
55 		density = 0.0f;
56 		categoryBits = 0x0001;
57 		maskBits = 0xFFFF;
58 		groupIndex = 0;
59 	}
60 
~b2ShapeDefb2ShapeDef61 	virtual ~b2ShapeDef() {}
62 
63 	void ComputeMass(b2MassData* massData) const;
64 
65 	b2ShapeType type;
66 	void* userData;
67 	b2Vec2 localPosition;
68 	float32 localRotation;
69 	float32 friction;
70 	float32 restitution;
71 	float32 density;
72 
73 	// The collision category bits. Normally you would just set one bit.
74 	uint16 categoryBits;
75 
76 	// The collision mask bits. This states the categories that this
77 	// shape would accept for collision.
78 	uint16 maskBits;
79 
80 	// Collision groups allow a certain group of objects to never collide (negative)
81 	// or always collide (positive). Zero means no collision group. Non-zero group
82 	// filtering always wins against the mask bits.
83 	int16 groupIndex;
84 };
85 
86 struct b2CircleDef : public b2ShapeDef
87 {
b2CircleDefb2CircleDef88 	b2CircleDef()
89 	{
90 		type = e_circleShape;
91 		radius = 1.0f;
92 	}
93 
94 	float32 radius;
95 };
96 
97 struct b2BoxDef : public b2ShapeDef
98 {
b2BoxDefb2BoxDef99 	b2BoxDef()
100 	{
101 		type = e_boxShape;
102 		extents.Set(1.0f, 1.0f);
103 	}
104 
105 	b2Vec2 extents;
106 };
107 
108 // Convex polygon, vertices must be in CCW order.
109 struct b2PolyDef : public b2ShapeDef
110 {
b2PolyDefb2PolyDef111 	b2PolyDef()
112 	{
113 		type = e_polyShape;
114 		vertexCount = 0;
115 	}
116 
117 	b2Vec2 vertices[b2_maxPolyVertices];
118 	int32 vertexCount;
119 };
120 
121 // Shapes are created automatically when a body is created.
122 // Client code does not normally interact with shapes.
123 class b2Shape
124 {
125 public:
126 	virtual bool TestPoint(const b2Vec2& p) = 0;
127 
128 	void* GetUserData();
129 
130 	b2ShapeType GetType() const;
131 
132 	// Get the parent body of this shape.
133 	b2Body* GetBody();
134 
135 	// Get the world position.
136 	const b2Vec2& GetPosition() const;
137 
138 	// Get the world rotation.
139 	const b2Mat22& GetRotationMatrix() const;
140 
141 	// Remove and then add proxy from the broad-phase.
142 	// This is used to refresh the collision filters.
143 	virtual void ResetProxy(b2BroadPhase* broadPhase) = 0;
144 
145 	// Get the next shape in the parent body's shape list.
146 	b2Shape* GetNext();
147 
148 	//--------------- Internals Below -------------------
149 
150 	static b2Shape* Create(	const b2ShapeDef* def,
151 							b2Body* body, const b2Vec2& newOrigin);
152 
153 	static void Destroy(b2Shape*& shape);
154 
155 	b2Shape(const b2ShapeDef* def, b2Body* body);
156 
157 	virtual ~b2Shape();
158 
159 	virtual void Synchronize(	const b2Vec2& position1, const b2Mat22& R1,
160 								const b2Vec2& position2, const b2Mat22& R2) = 0;
161 	virtual void QuickSync(const b2Vec2& position, const b2Mat22& R) = 0;
162 
163 	virtual b2Vec2 Support(const b2Vec2& d) const = 0;
164 	float32 GetMaxRadius() const;
165 
166 	void DestroyProxy();
167 
168 	b2Shape* m_next;
169 
170 	b2Mat22 m_R;
171 	b2Vec2 m_position;
172 
173 	b2ShapeType m_type;
174 
175 	void* m_userData;
176 
177 	b2Body* m_body;
178 
179 	float32 m_friction;
180 	float32 m_restitution;
181 
182 	float32 m_minRadius;
183 	float32 m_maxRadius;
184 
185 	uint16 m_proxyId;
186 	uint16 m_categoryBits;
187 	uint16 m_maskBits;
188 	int16 m_groupIndex;
189 };
190 
191 class b2CircleShape : public b2Shape
192 {
193 public:
194 	bool TestPoint(const b2Vec2& p);
195 
196 	void ResetProxy(b2BroadPhase* broadPhase);
197 
198 	//--------------- Internals Below -------------------
199 
200 	b2CircleShape(const b2ShapeDef* def, b2Body* body, const b2Vec2& newOrigin);
201 
202 	void Synchronize(	const b2Vec2& position1, const b2Mat22& R1,
203 						const b2Vec2& position2, const b2Mat22& R2);
204 	void QuickSync(const b2Vec2& position, const b2Mat22& R);
205 
206 	b2Vec2 Support(const b2Vec2& d) const;
207 
208 	// Local position in parent body
209 	b2Vec2 m_localPosition;
210 	float32 m_radius;
211 };
212 
213 // A convex polygon. The position of the polygon (m_position) is the
214 // position of the centroid. The vertices of the incoming polygon are pre-rotated
215 // according to the local rotation. The vertices are also shifted to be centered
216 // on the centroid. Since the local rotation is absorbed into the vertex
217 // coordinates, the polygon rotation is equal to the body rotation. However,
218 // the polygon position is centered on the polygon centroid. This simplifies
219 // some collision algorithms.
220 class b2PolyShape : public b2Shape
221 {
222 public:
223 	bool TestPoint(const b2Vec2& p);
224 
225 	void ResetProxy(b2BroadPhase* broadPhase);
226 
227 	//--------------- Internals Below -------------------
228 
229 	b2PolyShape(const b2ShapeDef* def, b2Body* body, const b2Vec2& newOrigin);
230 
231 	void Synchronize(	const b2Vec2& position1, const b2Mat22& R1,
232 						const b2Vec2& position2, const b2Mat22& R2);
233 	void QuickSync(const b2Vec2& position, const b2Mat22& R);
234 
235 	b2Vec2 Support(const b2Vec2& d) const;
236 
237 	// Local position of the shape centroid in parent body frame.
238 	b2Vec2 m_localCentroid;
239 
240 	// Local position oriented bounding box. The OBB center is relative to
241 	// shape centroid.
242 	b2OBB m_localOBB;
243 	b2Vec2 m_vertices[b2_maxPolyVertices];
244 	b2Vec2 m_coreVertices[b2_maxPolyVertices];
245 	int32 m_vertexCount;
246 	b2Vec2 m_normals[b2_maxPolyVertices];
247 };
248 
GetType()249 inline b2ShapeType b2Shape::GetType() const
250 {
251 	return m_type;
252 }
253 
GetUserData()254 inline void* b2Shape::GetUserData()
255 {
256 	return m_userData;
257 }
258 
GetBody()259 inline b2Body* b2Shape::GetBody()
260 {
261 	return m_body;
262 }
263 
GetNext()264 inline b2Shape* b2Shape::GetNext()
265 {
266 	return m_next;
267 }
268 
GetPosition()269 inline const b2Vec2& b2Shape::GetPosition() const
270 {
271 	return m_position;
272 }
273 
GetRotationMatrix()274 inline const b2Mat22& b2Shape::GetRotationMatrix() const
275 {
276 	return m_R;
277 }
278 
GetMaxRadius()279 inline float32 b2Shape::GetMaxRadius() const
280 {
281 	return m_maxRadius;
282 }
283 
284 
285 #endif
286