//--------------------------------------------------------------------------------------
// Copyright (C) 2008 http://shift.delblanco.es
//--------------------------------------------------------------------------------------
// SHIFT Videogame is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//--------------------------------------------------------------------------------------
/// \file 3DPhysics.h
/// Para manejar la física de los objetos de la escena.
/// Cada objeto de la escena puede tener asociado un sistema físico, todas las
/// operaciones relacionadas con el sistema físico se manejan desde este módulo
//--------------------------------------------------------------------------------------
#pragma once
#ifndef __C3DPHYSICS_H__
#define __C3DPHYSICS_H__
class C3DObject;

//--------------------------------------------------------------------------------------
/// Clase para manejar el sistema físico de los objetos de la escena.
//--------------------------------------------------------------------------------------
class C3DPhysics
{
friend C3DObject;

protected:  // Campos miembro

    bool                 m_bInit;               ///< Flag que indica si el objeto está inicializado

    float                m_fLSpeed;			    ///< Módulo de la velocidad lineal
    float                m_fLAcceleration;      ///< Módulo de la aceleración lineal
    float                m_fLFriction;			///< Módulo del rozamiento lineal
    D3DXVECTOR3			 m_pLDirection;			///< Vector normalizado de la dirección de desplazamiento lineal

    D3DXVECTOR3			 *m_pASpeed;			///< Velocidad angular en cada uno de los tres ejes
    D3DXVECTOR3			 *m_pAAcceleration;		///< Aceleración angular en cada uno de los tres ejes
    D3DXVECTOR3			 *m_pAFriction;			///< Rozamiento angular en cada uno de los tres ejes

    C3DObject            *m_pObject;            ///< Objeto asociado a esta física

    /// Constructor privado, sólo se podrá crear desde una instancia 3DObject
    C3DPhysics();
    /// Destructor
    ~C3DPhysics();

public: // Métodos públicos

    /// Inicializa el sistema físico
    bool initialize(C3DObject *Object);
    /// Aplica los parámetros físicos
    void update();
    /// Libera los parámetros físicos
    void Release();

    /// Función observadora del objeto asociado
    C3DObject *getObject(void)					{return m_pObject;}

    /// Establece la velocidad lineal actual
    void setLSpeed (float Val)                  {m_fLSpeed = Val;}
    /// Toma la velocidad lineal actual
    float getLSpeed (void)                      {return m_fLSpeed;}
    /// Añade una velocidad lineal a la existente
    void addLSpeed (float Val)                  {m_fLSpeed += Val;}

    /// Toma el vector normalizado de dirección lineal
    D3DXVECTOR3 *getLDirection (void)           {return &m_pLDirection;}
    /// Establece el vector normalizado de dirección lineal y la magnitud de velocidad lineal
    void setLDirection (D3DXVECTOR3 &Vec)       {D3DXVec3Normalize(&m_pLDirection, &Vec); m_fLSpeed = D3DXVec3Length(&Vec);}

    /// Establece la aceleración lineal actual
    void setLAcceleration (float Val)           {m_fLAcceleration = Val;}
    /// Toma la aceleración lineal actual
    float getLAcceleration (void)               {return m_fLAcceleration;}
    /// Añade una aceleración lineal a la existente
    void addLAcceleration (float Val)           {m_fLAcceleration += Val;}

    /// Establece la fricción lineal actual
    void setLFriction (float Val)               {m_fLFriction = Val;}
    /// Toma la fricción lineal actual
    float getLFriction (void)                   {return m_fLFriction;}

    /// Añade una rotación a la dirección de la velocidad lineal actual
    void addRotLDirection (D3DXVECTOR3 &Vec);
    /// Establece una rotación a la dirección de la velocidad lineal actual
    void setRotLDirection (D3DXVECTOR3 &Vec);
    /// Resetea la rotación de la dirección de la velocidad lineal actual
    void resetRotLDirection (void);

    /// Establece la velocidad angular actual
    void setASpeed (D3DXVECTOR3 &Vec);
    /// Toma la velocidad angular actual
    void getASpeed (D3DXVECTOR3 &Vec);
    /// Añade una velocidad angular a la existente
    void addASpeed (D3DXVECTOR3 &Vec);

    /// Establece la aceleración angular actual
    void setAAcceleration (D3DXVECTOR3 &Vec);
    /// Toma la aceleración angular actual
    void getAAcceleration (D3DXVECTOR3 &Vec);
    /// Añade una aceleración angular a la existente
    void addAAcceleration (D3DXVECTOR3 &Vec);

    /// Establece la fricción angular actual
    void setAFriction (D3DXVECTOR3 &Vec);
    /// Toma la fricción angular actual
    void getAFriction (D3DXVECTOR3 &Vec);
    /// Añade una fricción angular a la existente
    void addAFriction (D3DXVECTOR3 &Vec);

};

#endif
