src/PhysicsObject.hh
author terom
Sat, 06 Dec 2008 23:29:06 +0000
changeset 235 0a0c729365ee
parent 228 dbc1bb7a98b5
child 249 5647f58e37cd
permissions -rw-r--r--
code cleanup
#ifndef PHYSICS_OBJECT_HH
#define PHYSICS_OBJECT_HH

#include <ClanLib/display.h>

// Forward declares
class PhysicsObject;
struct Derivative;

#include "PhysicsWorld.hh"
#include "Vector.hh"
#include "Timer.hh"
#include "Config.hh"

// Type definitions
typedef Vector Force;


/**
 * PhysicObject class. A basic PhysicsObject class.
 */
class PhysicsObject {
protected:
    Vector position;
    Vector velocity;
    float mass;
    bool inAir; // Is the object "on the ground"
    float collision_elasticity;

    // Attributes for players
    float aim; // Aim direction (half circle)
    bool facingRight; // Player facing

    bool alive;
    bool shouldDelete;

    PhysicsObject *pivot;

    PhysicsObject(PhysicsWorld &world, float mass, Vector position, 
                  Vector velocity, bool enabled = true);
    virtual ~PhysicsObject (void);


    /**
     * Add force to the force queue to be applied on next tick.
     *
     * @param force Force vector
     */
    void applyForce(Force force);

    /**
     * Change player aim
     *
     * @param da Aim angle change
     */
    void changeAim(float da);
   
    /**
     * Set player facing.
     *
     * @param facingRight True if player is facing right.
     */
    void setFacing(bool facingRight);

    /**
     * Makes the player jump in the air.
     * @param direction -1: jump left, 0: jump up, 1: jump right
     */
    void jump(int direction);

    /** 
     * Handle ground-bounce
     *
     * @param normal Normal vector relative to which to bounce
     */
    void bounce(Vector normal);

    /**
     * Called on network clients to sync state from server
     *
     * @param position New position
     * @param velocity New velocity
     * @param inAir New inAir value
     * @param facingRight New facingRight value
     * @param aim New aim
     */
    virtual void updatePhysics(Vector position, Vector velocity, bool inAir, bool facingRight, float aim);

    /**
     * Put object to the objects list so that its movement will be calculated.
     */
    void enable (void);

    /**
     * Remove object from the objects list but don't delete the object itself.
     */
    void disable (void);

private:
    // TODO: I'd be tempted to use some already made ClanLib structure
    // here.  
    // Shape of the object. Edge points of the shape polygon.
    std::vector<Vector> shape;

    // TODO: Should these operations be moved to PhysicsWorld?
    // Force queue that is emptied on every tick
    std::queue<Force> forceq;

    /**
     * Handle player movement and apply forces.
     */
    void updatePosition(TimeMS dt);

    // TODO: Should these be moved to PhysicsWorld?
    /**
     * Use RK4 to integrate the effects of force over a time interwall.
     *
     * @param force Force to integrate
     * @param dt Time intervall
     */
    void integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick);

    /**
     * Evaluate the value of the derivative at given time
     *
     * @param force Force
     * @param dt Time
     * @param d Previous derivative
     */
    Derivative evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick);

    /**
     * Return object acceleration with given force.
     *
     * @param force Force
     * @return Acceleration
     */
    Vector acceleration(const Force &force);

    // TODO: If integration is moved to PhysicsWorld then this should
    // also move there.
    /**
     * Handle ground movement.
     *
     * @param right Boolean describing the movement direction.
     * @return New position
     */
    void walk(TimeMS, bool right);
    Vector walk_one_step(float, bool);

    /*
     * Handle collision. TODO: This is not used. It probably should
     * be?
     */
    virtual void onCollision() {}

    /*
     * TODO: This probably does some kind of collision
     * detection. Could be named/documented better.
     */
    bool possibleLocation(Vector loc);

public:
    PhysicsWorld &world;

    /**
     * Get current object position.
     *
     * @return Position vector
     */
    Vector getPosition();

    /**
     * Get current object velocity.
     *
     * @return Velocity vector
     */
    Vector getVelocity();

    /**
     * Return object shape.
     *
     * @return Polygon points
     */
    std::vector<Vector>& getShape();

    /**
     * Set object shape.
     *
     * @param shape Vector containing polygon poinst
     */
    void setShape(std::vector<Vector> shape);

    /**
     * Return object facing.
     *
     * @return Object facing (true if facing right)
     */
    bool getFacing();

    /**
     * Return object aim angle.
     *
     * @return Object aim angle
     */
    float getAim();

    /**
     * Returns facing+aim as a unit vector
     */
    Vector getDirection (void);

    /**
     *  Mark object as destroyed, it will be delete'd later
     */
    void destroy (void);

    /*
     * Had the object been destroyed?
     */
    bool isDestroyed (void);
    
    /**
     * Delete ourselves if we've been destroyed and return true, else return false
     */
    bool removeIfDestroyed (void);

    /**
     * Sets this object's pivot to the given value, which will then exert a force on this object
     */
    void setPivot (PhysicsObject *pivot);

    /**
     * Compute the force that this object (as a pivot) exerts on the given object
     */
    virtual float getPivotForce (PhysicsObject *bob);

    /**
     * Update object in physics simulation.
     */
    virtual void tick (TimeMS tick_length);

    /**
     * Draw object
     *
     * @param gc CL_GraphicContext
     */
    virtual void draw(CL_GraphicContext *gc);
};

// TODO: This could probably be moved somewhere else or removed
// completely.
struct Derivative {
    Vector dx; // Velocity
    Vector dv; // Acceleration
};

#endif