| author | terom |
| Mon, 08 Dec 2008 21:18:08 +0000 | |
| changeset 311 | 440763821484 |
| parent 299 | e4dacf550ba1 |
| child 317 | f325fad21f4f |
| permissions | -rw-r--r-- |
| 197 | 1 |
#ifndef PHYSICS_OBJECT_HH |
2 |
#define PHYSICS_OBJECT_HH |
|
3 |
||
4 |
#include <ClanLib/display.h> |
|
| 273 | 5 |
#include <utility> |
| 197 | 6 |
|
7 |
// Forward declares |
|
8 |
class PhysicsObject; |
|
9 |
struct Derivative; |
|
10 |
||
11 |
#include "PhysicsWorld.hh" |
|
12 |
#include "Vector.hh" |
|
| 205 | 13 |
#include "Timer.hh" |
| 197 | 14 |
#include "Config.hh" |
15 |
||
16 |
// Type definitions |
|
17 |
typedef Vector Force; |
|
| 265 | 18 |
|
19 |
enum ObjectType { PLAYER, PROJECTILE, ROPE };
|
|
| 197 | 20 |
|
| 264 | 21 |
enum FacingDirection {
|
22 |
FACING_LEFT, |
|
23 |
FACING_RIGHT |
|
24 |
}; |
|
| 197 | 25 |
|
26 |
/** |
|
27 |
* PhysicObject class. A basic PhysicsObject class. |
|
28 |
*/ |
|
29 |
class PhysicsObject {
|
|
|
282
e0e4dfc3e528
compiles cleanly with -Wall -Wextra -Wconversion, not tested, but that shouldn't break anything :)
terom
parents:
279
diff
changeset
|
30 |
public: |
|
e0e4dfc3e528
compiles cleanly with -Wall -Wextra -Wconversion, not tested, but that shouldn't break anything :)
terom
parents:
279
diff
changeset
|
31 |
PhysicsWorld &world; |
|
e0e4dfc3e528
compiles cleanly with -Wall -Wextra -Wconversion, not tested, but that shouldn't break anything :)
terom
parents:
279
diff
changeset
|
32 |
|
| 197 | 33 |
protected: |
34 |
Vector position; |
|
| 285 | 35 |
Vector previousPosition; |
| 197 | 36 |
Vector velocity; |
37 |
float mass; |
|
38 |
bool inAir; // Is the object "on the ground" |
|
39 |
float collision_elasticity; |
|
40 |
||
41 |
// Attributes for players |
|
42 |
float aim; // Aim direction (half circle) |
|
| 264 | 43 |
FacingDirection facing; // Player facing |
| 197 | 44 |
|
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
45 |
bool alive; |
| 225 | 46 |
bool shouldDelete; |
| 265 | 47 |
|
48 |
ObjectType type; |
|
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
49 |
|
| 228 | 50 |
PhysicsObject *pivot; |
51 |
||
|
279
e36f5e1a1c8d
let projectiles bounce, the new BounceBounce weapon puts the Physics engine into an infinite loop
terom
parents:
273
diff
changeset
|
52 |
PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity, ObjectType type, |
|
e36f5e1a1c8d
let projectiles bounce, the new BounceBounce weapon puts the Physics engine into an infinite loop
terom
parents:
273
diff
changeset
|
53 |
float collision_elasticity, bool enabled = true); |
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
54 |
virtual ~PhysicsObject (void); |
| 197 | 55 |
|
56 |
||
57 |
/** |
|
58 |
* Add force to the force queue to be applied on next tick. |
|
59 |
* |
|
60 |
* @param force Force vector |
|
61 |
*/ |
|
| 273 | 62 |
void applyForce(Force force, TimeMS dt = PHYSICS_TICK_MS); |
| 197 | 63 |
|
64 |
/** |
|
65 |
* Change player aim |
|
66 |
* |
|
67 |
* @param da Aim angle change |
|
68 |
*/ |
|
69 |
void changeAim(float da); |
|
70 |
||
71 |
/** |
|
72 |
* Set player facing. |
|
73 |
* |
|
74 |
* @param facingRight True if player is facing right. |
|
75 |
*/ |
|
| 264 | 76 |
void setFacing (FacingDirection facing); |
| 197 | 77 |
|
78 |
/** |
|
79 |
* Makes the player jump in the air. |
|
80 |
* @param direction -1: jump left, 0: jump up, 1: jump right |
|
81 |
*/ |
|
| 299 | 82 |
void jump (int direction); |
| 197 | 83 |
|
84 |
/** |
|
85 |
* Handle ground-bounce |
|
86 |
* |
|
87 |
* @param normal Normal vector relative to which to bounce |
|
88 |
*/ |
|
| 299 | 89 |
void bounce (Vector normal); |
| 197 | 90 |
|
91 |
/** |
|
92 |
* Called on network clients to sync state from server |
|
93 |
* |
|
94 |
* @param position New position |
|
95 |
* @param velocity New velocity |
|
96 |
* @param inAir New inAir value |
|
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
197
diff
changeset
|
97 |
* @param facingRight New facingRight value |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
197
diff
changeset
|
98 |
* @param aim New aim |
| 197 | 99 |
*/ |
| 299 | 100 |
virtual void updatePhysics (Vector position, Vector velocity, bool inAir, FacingDirection facing, float aim); |
| 197 | 101 |
|
| 225 | 102 |
/** |
103 |
* Put object to the objects list so that its movement will be calculated. |
|
104 |
*/ |
|
105 |
void enable (void); |
|
106 |
||
107 |
/** |
|
108 |
* Remove object from the objects list but don't delete the object itself. |
|
109 |
*/ |
|
110 |
void disable (void); |
|
111 |
||
| 197 | 112 |
private: |
113 |
// Shape of the object. Edge points of the shape polygon. |
|
114 |
std::vector<Vector> shape; |
|
115 |
||
116 |
// Force queue that is emptied on every tick |
|
| 273 | 117 |
std::queue<std::pair<Force, TimeMS> > forceq; |
| 197 | 118 |
|
119 |
/** |
|
120 |
* Handle player movement and apply forces. |
|
121 |
*/ |
|
| 299 | 122 |
void updatePosition (TimeMS dt); |
| 197 | 123 |
|
124 |
// TODO: Should these be moved to PhysicsWorld? |
|
125 |
/** |
|
126 |
* Use RK4 to integrate the effects of force over a time interwall. |
|
127 |
* |
|
128 |
* @param force Force to integrate |
|
129 |
* @param dt Time intervall |
|
130 |
*/ |
|
| 299 | 131 |
void integrate (Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick); |
| 197 | 132 |
|
133 |
/** |
|
134 |
* Evaluate the value of the derivative at given time |
|
135 |
* |
|
136 |
* @param force Force |
|
137 |
* @param dt Time |
|
138 |
* @param d Previous derivative |
|
139 |
*/ |
|
| 299 | 140 |
Derivative evaluate (Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick); |
| 197 | 141 |
|
142 |
/** |
|
143 |
* Return object acceleration with given force. |
|
144 |
* |
|
145 |
* @param force Force |
|
146 |
* @return Acceleration |
|
147 |
*/ |
|
| 299 | 148 |
Vector acceleration (const Force &force); |
| 197 | 149 |
|
| 249 | 150 |
/** |
| 197 | 151 |
* Handle ground movement. |
152 |
* |
|
153 |
* @param right Boolean describing the movement direction. |
|
154 |
* @return New position |
|
155 |
*/ |
|
| 299 | 156 |
void walk (TimeMS, bool right); |
157 |
Vector walk_one_step (float, bool); |
|
| 197 | 158 |
|
| 288 | 159 |
public: |
| 249 | 160 |
/** |
161 |
* Define object behaviour on collisions. |
|
|
282
e0e4dfc3e528
compiles cleanly with -Wall -Wextra -Wconversion, not tested, but that shouldn't break anything :)
terom
parents:
279
diff
changeset
|
162 |
* |
|
e0e4dfc3e528
compiles cleanly with -Wall -Wextra -Wconversion, not tested, but that shouldn't break anything :)
terom
parents:
279
diff
changeset
|
163 |
* XXX: make this pure-virtual |
| 197 | 164 |
*/ |
| 288 | 165 |
virtual void onCollision (Vector collisionPoint, PhysicsObject *other = NULL); |
| 272 | 166 |
|
| 249 | 167 |
/** |
| 287 | 168 |
* Return the type of the physics object (player, projectile...) |
169 |
*/ |
|
170 |
ObjectType getType (void) const; |
|
171 |
||
172 |
/** |
|
| 249 | 173 |
* Checks if it is possible for the object to be in the given |
174 |
* location. |
|
| 197 | 175 |
*/ |
| 299 | 176 |
bool possibleLocation (Vector loc); |
| 197 | 177 |
|
178 |
/** |
|
179 |
* Get current object position. |
|
180 |
* |
|
181 |
* @return Position vector |
|
182 |
*/ |
|
|
257
549783d71e51
add a handful of consts to PhysicsObject and modify draw to use getCoordinate, and replace old skin.png with new skin.png
terom
parents:
255
diff
changeset
|
183 |
Vector getPosition (void) const; |
|
255
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
252
diff
changeset
|
184 |
|
|
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
252
diff
changeset
|
185 |
/** |
| 285 | 186 |
* Set previous object position. |
187 |
* |
|
188 |
* @param Position vector |
|
189 |
*/ |
|
190 |
void setPosition (Vector pos); |
|
191 |
||
192 |
/** |
|
193 |
* Get previous object position. |
|
194 |
* |
|
195 |
* @return Position vector |
|
196 |
*/ |
|
197 |
Vector getPreviousPosition (void) const; |
|
198 |
||
199 |
/** |
|
|
255
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
252
diff
changeset
|
200 |
* Get current object screen coordinates |
|
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
252
diff
changeset
|
201 |
* |
|
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
252
diff
changeset
|
202 |
* @return PixelCoordinate position |
|
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
252
diff
changeset
|
203 |
*/ |
|
257
549783d71e51
add a handful of consts to PhysicsObject and modify draw to use getCoordinate, and replace old skin.png with new skin.png
terom
parents:
255
diff
changeset
|
204 |
PixelCoordinate getCoordinate (void) const; |
| 197 | 205 |
|
206 |
/** |
|
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
207 |
* Get current object velocity. |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
208 |
* |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
209 |
* @return Velocity vector |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
210 |
*/ |
| 299 | 211 |
Vector getVelocity (void) const; |
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
212 |
|
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
213 |
/** |
| 197 | 214 |
* Return object shape. |
215 |
* |
|
216 |
* @return Polygon points |
|
217 |
*/ |
|
| 299 | 218 |
const std::vector<Vector>& getShape (void) const; |
| 197 | 219 |
|
220 |
/** |
|
221 |
* Set object shape. |
|
222 |
* |
|
223 |
* @param shape Vector containing polygon poinst |
|
224 |
*/ |
|
225 |
void setShape(std::vector<Vector> shape); |
|
226 |
||
227 |
/** |
|
228 |
* Return object facing. |
|
229 |
* |
|
230 |
* @return Object facing (true if facing right) |
|
231 |
*/ |
|
| 264 | 232 |
FacingDirection getFacing() const; |
| 197 | 233 |
|
234 |
/** |
|
235 |
* Return object aim angle. |
|
236 |
* |
|
237 |
* @return Object aim angle |
|
238 |
*/ |
|
|
257
549783d71e51
add a handful of consts to PhysicsObject and modify draw to use getCoordinate, and replace old skin.png with new skin.png
terom
parents:
255
diff
changeset
|
239 |
float getAim() const; |
| 197 | 240 |
|
241 |
/** |
|
| 235 | 242 |
* Returns facing+aim as a unit vector |
243 |
*/ |
|
|
257
549783d71e51
add a handful of consts to PhysicsObject and modify draw to use getCoordinate, and replace old skin.png with new skin.png
terom
parents:
255
diff
changeset
|
244 |
Vector getDirection (void) const; |
| 235 | 245 |
|
246 |
/** |
|
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
247 |
* Mark object as destroyed, it will be delete'd later |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
248 |
*/ |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
249 |
void destroy (void); |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
250 |
|
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
251 |
/* |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
252 |
* Had the object been destroyed? |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
253 |
*/ |
| 299 | 254 |
bool isAlive (void); |
|
222
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
255 |
|
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
256 |
/** |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
257 |
* Delete ourselves if we've been destroyed and return true, else return false |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
258 |
*/ |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
259 |
bool removeIfDestroyed (void); |
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
260 |
|
|
293ddf4c067d
reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
ekku
parents:
221
diff
changeset
|
261 |
/** |
| 228 | 262 |
* Sets this object's pivot to the given value, which will then exert a force on this object |
263 |
*/ |
|
264 |
void setPivot (PhysicsObject *pivot); |
|
265 |
||
266 |
/** |
|
|
268
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
267 |
* Checks if object collides with other objects |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
268 |
* |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
269 |
* @param obj Other PhysicsObject |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
270 |
*/ |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
271 |
bool collides (const PhysicsObject &obj); |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
272 |
|
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
273 |
/** |
| 228 | 274 |
* Compute the force that this object (as a pivot) exerts on the given object |
275 |
*/ |
|
276 |
virtual float getPivotForce (PhysicsObject *bob); |
|
277 |
||
278 |
/** |
|
| 197 | 279 |
* Update object in physics simulation. |
280 |
*/ |
|
| 221 | 281 |
virtual void tick (TimeMS tick_length); |
| 197 | 282 |
}; |
283 |
||
284 |
struct Derivative {
|
|
285 |
Vector dx; // Velocity |
|
286 |
Vector dv; // Acceleration |
|
287 |
}; |
|
288 |
||
|
268
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
289 |
/** |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
290 |
* Returns the "sign" of the cross product between given points. In |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
291 |
* practice the sign of the return value tels on which side of the |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
292 |
* line drawn between p1 and p2 the point p3 is. |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
293 |
* |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
294 |
* @param p1 Line start point |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
295 |
* @param p2 Line end point |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
296 |
* @param p3 Point |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
297 |
* @return Variable, the sign of which tells on which side of the line p3 is. |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
298 |
*/ |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
299 |
int8_t crossProduct(const Vector &p1, const Vector &p2, const Vector &p3); |
|
0b96b88af335
Added collision detection method to PhysicsObject. Not tested.
saiam
parents:
265
diff
changeset
|
300 |
|
| 197 | 301 |
#endif |