src/proto2/Physics.hh
author nireco
Mon, 24 Nov 2008 21:38:04 +0000
changeset 101 1c52bd7fbc43
parent 98 606c419e42a7
child 105 91e3f3806b31
permissions -rw-r--r--
dot production vec*scalar
#ifndef PHYSICS_HH
#define PHYSICS_HH

#include "Vector.hh"

#include <vector>
#include <queue>
#include <ClanLib/core.h>

typedef uint16_t TimeMS;

const TimeMS PHYSICS_TICK_MS = 10;

enum TerrainType {EMPTY, DIRT, ROCK};

const Vector DIRECTIONS[] = { Vector(0,-1), Vector(1,-1), Vector(1,0), Vector(1,1),
							Vector(0,1), Vector(-1,1), Vector(-1,0), Vector(-1,-1) };

// forward-declare
class PhysicsObject;
typedef Vector Force;
struct Derivative;

class PhysicsWorld {
    friend class PhysicsObject;
    
private:
    CL_Timer tick_timer;
    
protected:
    std::vector<PhysicsObject*> objects;
    Vector gravity;
    Vector dimensions;


    std::vector<std::vector<TerrainType> > terrain;

    CL_SlotContainer slots;
    
    PhysicsWorld (Vector gravity, Vector dimensions);


public:
    
    void addObject (PhysicsObject *object);

    void tick (void);
    void generateTerrain (int seed);
    bool collided (Vector oldPos, Vector newPos);

    Vector getNormal(Vector hitPoint, Vector prevPoint);

    TerrainType getType(Vector pos) const;
};

class PhysicsObject {
protected:
    PhysicsWorld &world;
    
    float mass;
    Vector position;
    Vector velocity;
    // Whether the object (worms mainly) is in the air 
    // or firmly on the ground. Affects to physics.
    bool inAir;

	// Shape of the object. We use a polygon with 4 edges
	// to make easy to draw with Clanlib. The coordinates
	// are relative to the center point.
	std::vector<Vector> shape;

    // Force queue that is emptied on every tick
    std::queue<Force> forceq;
    Vector posAfterTick;
    Vector velAfterTick;

	/**
	 * @param shape Corners of the four sided polygon.
	 */
    PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity);
    
    /**
     * Used to handle in-air movement
     */    
    virtual void applyForce (Force force, TimeMS dt);

    /**
     * Called on network clients to sync state from server
     */
    void updatePhysics (Vector position, Vector velocity);

    /**
     * Handle ground movement
     *
     * @return new position
     */
    Vector walk (bool right);

    /**
     * Handle ground-jumping
     */
    void jump (void);

    /**
     * Handle ground-bounce
     */
    void bounce (Vector normal);

private:
    void updatePosition (void);
	bool possibleLocation (Vector loc);

    /**
     * Use RK4 to integrate the effects of force over a time intervall.
     */
    void integrate(Force force, TimeMS dt);
    Derivative evaluate(Force force, TimeMS dt, Derivative &d);
    Vector acceleration(const Force &force);

public:
    Vector getPosition (void);
	std::vector<Vector>& getShape(void);
	void setShape (std::vector<Vector> shape);
    
    void tick (void);
};

struct Derivative {
    Vector dx; // Velocity
    Vector dv; // Acceleration
};



#endif