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