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 TEST_H
20 #define TEST_H
21 
22 #include <Box2D/Box2D.h>
23 #include "Render.h"
24 
25 #include <cstdlib>
26 
27 class Test;
28 struct Settings;
29 
30 typedef Test* TestCreateFcn();
31 
32 #define	RAND_LIMIT	32767
33 
34 /// Random number in range [-1,1]
RandomFloat()35 inline float32 RandomFloat()
36 {
37 	float32 r = (float32)(std::rand() & (RAND_LIMIT));
38 	r /= RAND_LIMIT;
39 	r = 2.0f * r - 1.0f;
40 	return r;
41 }
42 
43 /// Random floating point number in range [lo, hi]
RandomFloat(float32 lo,float32 hi)44 inline float32 RandomFloat(float32 lo, float32 hi)
45 {
46 	float32 r = (float32)(std::rand() & (RAND_LIMIT));
47 	r /= RAND_LIMIT;
48 	r = (hi - lo) * r + lo;
49 	return r;
50 }
51 
52 /// Test settings. Some can be controlled in the GUI.
53 struct Settings
54 {
SettingsSettings55 	Settings() :
56 		viewCenter(0.0f, 20.0f),
57 		hz(60.0f),
58 		velocityIterations(8),
59 		positionIterations(3),
60 		drawShapes(1),
61 		drawJoints(1),
62 		drawAABBs(0),
63 		drawPairs(0),
64 		drawContactPoints(0),
65 		drawContactNormals(0),
66 		drawContactForces(0),
67 		drawFrictionForces(0),
68 		drawCOMs(0),
69 		drawStats(0),
70 		drawProfile(0),
71 		enableWarmStarting(1),
72 		enableContinuous(1),
73 		enableSubStepping(0),
74 		pause(0),
75 		singleStep(0)
76 		{}
77 
78 	b2Vec2 viewCenter;
79 	float32 hz;
80 	int32 velocityIterations;
81 	int32 positionIterations;
82 	int32 drawShapes;
83 	int32 drawJoints;
84 	int32 drawAABBs;
85 	int32 drawPairs;
86 	int32 drawContactPoints;
87 	int32 drawContactNormals;
88 	int32 drawContactForces;
89 	int32 drawFrictionForces;
90 	int32 drawCOMs;
91 	int32 drawStats;
92 	int32 drawProfile;
93 	int32 enableWarmStarting;
94 	int32 enableContinuous;
95 	int32 enableSubStepping;
96 	int32 pause;
97 	int32 singleStep;
98 };
99 
100 struct TestEntry
101 {
102 	const char *name;
103 	TestCreateFcn *createFcn;
104 };
105 
106 extern TestEntry g_testEntries[];
107 // This is called when a joint in the world is implicitly destroyed
108 // because an attached body is destroyed. This gives us a chance to
109 // nullify the mouse joint.
110 class DestructionListener : public b2DestructionListener
111 {
112 public:
SayGoodbye(b2Fixture * fixture)113 	void SayGoodbye(b2Fixture* fixture) { B2_NOT_USED(fixture); }
114 	void SayGoodbye(b2Joint* joint);
115 
116 	Test* test;
117 };
118 
119 const int32 k_maxContactPoints = 2048;
120 
121 struct ContactPoint
122 {
123 	b2Fixture* fixtureA;
124 	b2Fixture* fixtureB;
125 	b2Vec2 normal;
126 	b2Vec2 position;
127 	b2PointState state;
128 };
129 
130 class Test : public b2ContactListener
131 {
132 public:
133 
134 	Test();
135 	virtual ~Test();
136 
SetTextLine(int32 line)137 	void SetTextLine(int32 line) { m_textLine = line; }
138     void DrawTitle(int x, int y, const char *string);
139 	virtual void Step(Settings* settings);
Keyboard(unsigned char key)140 	virtual void Keyboard(unsigned char key) { B2_NOT_USED(key); }
KeyboardUp(unsigned char key)141 	virtual void KeyboardUp(unsigned char key) { B2_NOT_USED(key); }
142 	void ShiftMouseDown(const b2Vec2& p);
143 	virtual void MouseDown(const b2Vec2& p);
144 	virtual void MouseUp(const b2Vec2& p);
145 	void MouseMove(const b2Vec2& p);
146 	void LaunchBomb();
147 	void LaunchBomb(const b2Vec2& position, const b2Vec2& velocity);
148 
149 	void SpawnBomb(const b2Vec2& worldPt);
150 	void CompleteBombSpawn(const b2Vec2& p);
151 
152 	// Let derived tests know that a joint was destroyed.
JointDestroyed(b2Joint * joint)153 	virtual void JointDestroyed(b2Joint* joint) { B2_NOT_USED(joint); }
154 
155 	// Callbacks for derived classes.
BeginContact(b2Contact * contact)156 	virtual void BeginContact(b2Contact* contact) { B2_NOT_USED(contact); }
EndContact(b2Contact * contact)157 	virtual void EndContact(b2Contact* contact) { B2_NOT_USED(contact); }
158 	virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
PostSolve(const b2Contact * contact,const b2ContactImpulse * impulse)159 	virtual void PostSolve(const b2Contact* contact, const b2ContactImpulse* impulse)
160 	{
161 		B2_NOT_USED(contact);
162 		B2_NOT_USED(impulse);
163 	}
164 
165 protected:
166 	friend class DestructionListener;
167 	friend class BoundaryListener;
168 	friend class ContactListener;
169 
170 	b2Body* m_groundBody;
171 	b2AABB m_worldAABB;
172 	ContactPoint m_points[k_maxContactPoints];
173 	int32 m_pointCount;
174 	DestructionListener m_destructionListener;
175 	DebugDraw m_debugDraw;
176 	int32 m_textLine;
177 	b2World* m_world;
178 	b2Body* m_bomb;
179 	b2MouseJoint* m_mouseJoint;
180 	b2Vec2 m_bombSpawnPoint;
181 	bool m_bombSpawning;
182 	b2Vec2 m_mouseWorld;
183 	int32 m_stepCount;
184 
185 	b2Profile m_maxProfile;
186 	b2Profile m_totalProfile;
187 };
188 
189 #endif
190