terom@185: #ifndef PHYSICS_HH terom@185: #define PHYSICS_HH terom@185: terom@185: #include terom@185: #include terom@185: #include terom@185: #include terom@185: #include terom@185: terom@185: #include "Vector.hh" terom@185: #include "Config.hh" terom@185: #include "Terrain.hh" terom@185: terom@185: // Forward declares terom@185: class PhysicsWorld; terom@185: class PhysicsObject; terom@185: class PlayerObject; terom@185: class ProjectileObject; terom@185: class Shape; terom@185: struct Derivative; terom@185: terom@185: // Type definitions terom@185: typedef uint16_t TimeMS; terom@185: typedef Vector Force; terom@185: terom@185: /** terom@185: * PhysicsWorld class. PhysicsWorld contains PhysicsObjects that are terom@185: * simulated in the PhysicsWorld. terom@185: */ terom@185: class PhysicsWorld : public Terrain { terom@185: friend class PhysicsObject; terom@185: terom@185: private: terom@185: CL_Timer tick_timer; terom@185: uint32_t tick_counter; terom@185: terom@185: // Terrain terrain; terom@185: terom@185: protected: terom@185: std::list players; terom@185: std::list projectiles; terom@185: // std::vector objects; terom@185: terom@185: // Contains connections between signals and slots terom@185: CL_SlotContainer slots; terom@185: terom@185: PhysicsWorld(Vector gravity, Vector dimensions); terom@185: terom@185: // TODO: Should these be somewhere else? terom@185: Vector dimensions; terom@185: Vector gravity; terom@185: terom@185: terom@185: terom@185: public: terom@185: // TODO: Replace addObject with these? terom@185: //void addPlayerObject(PlayerObject *object); terom@185: //void addProjectileObject(ProjectileObject *object); terom@185: terom@185: /** terom@185: * Add object to the PhysicsWorld. terom@185: * terom@185: * @param object Pointer to the PhysicsObject to add. terom@185: */ terom@185: void addPlayerObject(PhysicsObject *object); terom@185: terom@185: void addProjectile(PhysicsObject *projectile); terom@185: terom@185: /** terom@185: * Advance one time step in physics simulation. terom@185: */ terom@185: void tick(); terom@185: terom@185: /** terom@185: * Get current tick in physics simulation. terom@185: * terom@185: * @return tick Current simulation tick. terom@185: */ terom@185: uint32_t getTick(); terom@185: terom@185: virtual void draw(CL_GraphicContext *gc); terom@185: terom@185: // TODO This should probably be protected or in GameStat or in GameStatee terom@185: }; terom@185: terom@185: /** terom@185: * PhysicObject class. A basic PhysicsObject class. terom@185: */ terom@185: class PhysicsObject { terom@185: protected: terom@185: // This probably shouldn't be done this way. terom@185: PhysicsWorld &world; terom@185: terom@185: Vector position; terom@185: Vector velocity; terom@185: float mass; terom@185: bool inAir; // Is the object "on the ground" terom@185: float collision_elasticity; terom@185: terom@185: // Attributes for players terom@185: float aim; // Aim direction (half circle) terom@185: bool facingRight; // Player facing terom@185: terom@185: // terom@185: int reloadTimer; terom@185: terom@185: PhysicsObject(PhysicsWorld &world, float mass, Vector position, terom@185: Vector velocity); terom@185: ~PhysicsObject() {} terom@185: terom@185: terom@185: /** terom@185: * Add force to the force queue to be applied on next tick. terom@185: * terom@185: * @param force Force vector terom@185: */ terom@185: void applyForce(Force force); terom@185: terom@185: /** terom@185: * Change player aim terom@185: * terom@185: * @param da Aim angle change terom@185: */ terom@185: void changeAim(float da); terom@185: terom@185: /** terom@185: * Set player facing. terom@185: * terom@185: * @param facingRight True if player is facing right. terom@185: */ terom@185: void setFacing(bool facingRight); terom@185: terom@185: /** terom@185: * Makes the player jump in the air. terom@185: * @param direction -1: jump left, 0: jump up, 1: jump right terom@185: */ terom@185: void jump(int direction); terom@185: terom@185: /** terom@185: * Handle ground-bounce terom@185: * terom@185: * @param normal Normal vector relative to which to bounce terom@185: */ terom@185: void bounce(Vector normal); terom@185: terom@185: /** terom@185: * Called on network clients to sync state from server terom@185: * terom@185: * @param position New position terom@185: * @param velocity New velocity terom@185: * @param inAir New inAir value terom@185: */ terom@185: void updatePhysics(Vector position, Vector velocity, bool inAir); terom@185: terom@185: private: terom@185: // TODO: I'd be tempted to use some already made ClanLib structure terom@185: // here. terom@185: // Shape of the object. Edge points of the shape polygon. terom@185: std::vector shape; terom@185: terom@185: // TODO: Should these operations be moved to PhysicsWorld? terom@185: // Force queue that is emptied on every tick terom@185: std::queue forceq; terom@185: terom@185: /** terom@185: * Handle player movement and apply forces. terom@185: */ terom@185: void updatePosition(); terom@185: terom@185: // TODO: Should these be moved to PhysicsWorld? terom@185: /** terom@185: * Use RK4 to integrate the effects of force over a time interwall. terom@185: * terom@185: * @param force Force to integrate terom@185: * @param dt Time intervall terom@185: */ terom@185: void integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick); terom@185: terom@185: /** terom@185: * Evaluate the value of the derivative at given time terom@185: * terom@185: * @param force Force terom@185: * @param dt Time terom@185: * @param d Previous derivative terom@185: */ terom@185: Derivative evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick); terom@185: terom@185: /** terom@185: * Return object acceleration with given force. terom@185: * terom@185: * @param force Force terom@185: * @return Acceleration terom@185: */ terom@185: Vector acceleration(const Force &force); terom@185: terom@185: // TODO: If integration is moved to PhysicsWorld then this should terom@185: // also move there. terom@185: /** terom@185: * Handle ground movement. terom@185: * terom@185: * @param right Boolean describing the movement direction. terom@185: * @return New position terom@185: */ terom@185: Vector walk(TimeMS, bool right); nireco@189: Vector walk_one_step(float, bool); terom@185: terom@185: /* terom@185: * Handle collision. TODO: This is not used. It probably should terom@185: * be? terom@185: */ terom@185: virtual void onCollision() {} terom@185: terom@185: /* terom@185: * TODO: This probably does some kind of collision terom@185: * detection. Could be named/documented better. terom@185: */ terom@185: bool possibleLocation(Vector loc); terom@185: terom@185: public: terom@185: /** terom@185: * Get current object position. terom@185: * terom@185: * @return Position vector terom@185: */ terom@185: Vector getPosition(); terom@185: terom@185: /** terom@185: * Return object shape. terom@185: * terom@185: * @return Polygon points terom@185: */ terom@185: std::vector& getShape(); terom@185: terom@185: /** terom@185: * Set object shape. terom@185: * terom@185: * @param shape Vector containing polygon poinst terom@185: */ terom@185: void setShape(std::vector shape); terom@185: terom@185: /** terom@185: * Return object facing. terom@185: * terom@185: * @return Object facing (true if facing right) terom@185: */ terom@185: bool getFacing(); terom@185: terom@185: /** terom@185: * Return object aim angle. terom@185: * terom@185: * @return Object aim angle terom@185: */ terom@185: float getAim(); terom@185: terom@185: /** terom@185: * Update object in physics simulation. terom@185: */ terom@185: void tick(); terom@185: terom@185: /** terom@185: * @return whether this PhysicsObject can shoot or not terom@185: * This is in PhysicsObject for larpa-like shots terom@185: */ terom@185: bool canShoot(); terom@185: terom@185: /** terom@185: * Draw object terom@185: * terom@185: * @param gc CL_GraphicContext terom@185: */ terom@185: virtual void draw(CL_GraphicContext *gc); terom@185: }; terom@185: terom@185: // TODO: This could probably be moved somewhere else or removed terom@185: // completely. terom@185: struct Derivative { terom@185: Vector dx; // Velocity terom@185: Vector dv; // Acceleration terom@185: }; terom@185: terom@185: terom@185: // TODO: These are drafts terom@185: /** terom@185: * PlayerObject class. Represents a player in the physics engine. terom@185: */ terom@185: //class PlayerObject : public PhysicsObject { terom@185: terom@185: //}; terom@185: terom@185: /** terom@185: * ProjectileObject class. Represents different projectiles in the terom@185: * physics (i.e. not players) in the physics engine. terom@185: */ terom@185: //class ProjectileObject : public PhysicsObject { terom@185: terom@185: //}; terom@185: terom@185: #endif