///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-1996 Virtual Design All Rights Reserved.
//
// Permission to use,  copy,  modify,  and  distribute  this  software and its
// documentation for NON-COMMERCIAL purposes and without fee is hereby granted.
//
// VIRTUAL DESIGN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
// OF THE SOFTWARE, EITHER EXPRESS  OR  IMPLIED,  INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// OR NON-INFRINGEMENT. VIRTUAL DESIGN SHALL  NOT  BE LIABLE FOR ANY DAMAGES
// SUFFERED BY  LICENSEE AS A RESULT OF USING,  MODIFYING OR DISTRIBUTING THIS
// SOFTWARE OR ITS DERIVATIVES.
//
// THIS SOFTWARE  IS   NOT  DESIGNED  OR  INTENDED FOR USE OR RESALE AS ONLINE
// OR NOT ONLINE CONTROL  EQUIPMENT IN HAZARDOUS  ENVIRONMENTS REQUIRING  FAIL-
// SAFE PERFORMANCE,  SUCH  AS  IN   THE   OPERATION   OF  NUCLEAR  FACILITIES,
// AIRCRAFT   NAVIGATION  OR  COMMUNICATION  SYSTEMS,  AIR   TRAFFIC   CONTROL,
// DIRECT LIFE  SUPPORT  MACHINES, OR WEAPONS SYSTEMS, IN  WHICH  THE  FAILURE
// OF  THE SOFTWARE COULD  LEAD DIRECTLY  TO DEATH, PERSONAL INJURY, OR SEVERE
// PHYSICAL OR ENVIRONMENTAL  DAMAGE ("HIGH RISK ACTIVITIES").  VIRTUAL DESIGN
// SPECIFICALLY DISCLAIMS  ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH
// RISK ACTIVITIES.
///////////////////////////////////////////////////////////////////////////////

/**
 * Classe des matrices de transformation 3D
 * @author Guillaume Pelletier.
 * @version 1.0
 */

class Matrice44
 {
    public float m_xx, m_xy, m_xz, m_xw,
                 m_yx, m_yy, m_yz, m_yw,
                 m_zx, m_zy, m_zz, m_zw,
                 m_wx, m_wy, m_wz, m_ww;

    public Matrice44 () { setNull() ; }

    /**
     * Multiplication de la matrice par une autre matrice 44.
     */
    public void multiplyByMatrix ( Matrice44 p_m )
       {
       float l_xx = m_xx * p_m.m_xx + m_xy * p_m.m_yx +
                    m_xz * p_m.m_zx + m_xw * p_m.m_wx ;

       float l_xy = m_xx * p_m.m_xy + m_xy * p_m.m_yy +
                    m_xz * p_m.m_zy + m_xw * p_m.m_wy ;

       float l_xz = m_xx * p_m.m_xz + m_xy * p_m.m_yz +
                    m_xz * p_m.m_zz + m_xw * p_m.m_wz ;

       float l_xw = m_xx * p_m.m_xw + m_xy * p_m.m_yw +
                    m_xz * p_m.m_zw + m_xw * p_m.m_ww ;

       float l_yx = m_yx * p_m.m_xx + m_yy * p_m.m_yx +
                    m_yz * p_m.m_zx + m_yw * p_m.m_wx ;

       float l_yy = m_yx * p_m.m_xy + m_yy * p_m.m_yy +
                    m_yz * p_m.m_zy + m_yw * p_m.m_wy ;

       float l_yz = m_yx * p_m.m_xz + m_yy * p_m.m_yz +
                    m_yz * p_m.m_zz + m_yw * p_m.m_wz ;

       float l_yw = m_yx * p_m.m_xw + m_yy * p_m.m_yw +
                    m_yz * p_m.m_zw + m_yw * p_m.m_ww ;

       float l_zx = m_zx * p_m.m_xx + m_zy * p_m.m_yx +
                    m_zz * p_m.m_zx + m_zw * p_m.m_wx ;

       float l_zy = m_zx * p_m.m_xy + m_zy * p_m.m_yy +
                    m_zz * p_m.m_zy + m_zw * p_m.m_wy ;

       float l_zz = m_zx * p_m.m_xz + m_zy * p_m.m_yz +
                    m_zz * p_m.m_zz + m_zw * p_m.m_wz ;

       float l_zw = m_zx * p_m.m_xw + m_zy * p_m.m_yw +
                    m_zz * p_m.m_zw + m_zw * p_m.m_ww ;

       float l_wx = m_wx * p_m.m_xx + m_wy * p_m.m_yx +
                    m_wz * p_m.m_zx + m_ww * p_m.m_wx ;

       float l_wy = m_wx * p_m.m_xy + m_wy * p_m.m_yy +
                    m_wz * p_m.m_zy + m_ww * p_m.m_wy ;

       float l_wz = m_wx * p_m.m_xz + m_wy * p_m.m_yz +
                    m_wz * p_m.m_zz + m_ww * p_m.m_wz ;

       float l_ww = m_wx * p_m.m_xw + m_wy * p_m.m_yw +
                    m_wz * p_m.m_zw + m_ww * p_m.m_ww ;

       m_xx = l_xx ;
       m_xy = l_xy ;
       m_xz = l_xz ;
       m_xw = l_xw ;

       m_yx = l_yx ;
       m_yy = l_yy ;
       m_yz = l_yz ;
       m_yw = l_yw ;

       m_zx = l_zx ;
       m_zy = l_zy ;
       m_zz = l_zz ;
       m_zw = l_zw ;

       m_wx = l_wx ;
       m_wy = l_wy ;
       m_wz = l_wz ;
       m_ww = l_ww ;
       }

    /**
     * Initialisation de la matrice identitée.
     */
    public void setIdentity()
     {
     setNull();
     m_xx = m_yy = m_zz = m_ww = 1 ;
     }

    /**
     * Initialisation de la matrice nulle.
     */
    public void setNull ()
     { m_xx = m_xy = m_xz = m_xw = 0 ;
       m_yx = m_yy = m_yz = m_yw = 0 ;
       m_zx = m_zy = m_zz = m_zw = 0 ;
       m_wx = m_wy = m_wz = m_ww = 0 ; }

    /**
     * Initialisation de la matrice de translation X.
     */
    public void setTranslateX( float p_x ) { m_wx = p_x ; }

    /**
     * Initialisation de la matrice de translation Y.
     */
    public void setTranslateY( float p_y ) { m_wy = p_y ; }

    /**
     * Initialisation de la matrice de translation Z.
     */
    public void setTranslateZ( float p_z ) { m_wz = p_z ; }

    /**
     * Initialisation de la matrice de rotation x.
     */
    public void setRotateX( float p_cos, float p_sin )
      {
      setIdentity();
      m_yy =  p_cos ;
      m_zz =  p_cos ;
      m_yz =  p_sin ;
      m_zy = -p_sin ;
      }

    /**
     * Initialisation de la matrice de rotation y.
     */
    public void setRotateY( float p_cos, float p_sin )
      {
      setIdentity();
      m_xx =  p_cos ;
      m_zz =  p_cos ;
      m_zx =  p_sin ;
      m_xz = -p_sin ;
      }

    /**
     * Initialisation de la matrice de rotation Z.
     */
    public void setRotateZ( float p_cos, float p_sin )
      {
      setIdentity();
      m_xx =  p_cos ;
      m_yy =  p_cos ;
      m_xy =  p_sin ;
      m_yx = -p_sin ;
      }

    /**
     * Initialisation de la matrice de changement d'echelle X.
     */
    public void setScaleX( float p_s)
      {
      m_xx = p_s ;
      }

    /**
     * Initialisation de la matrice de changement d'echelle Y.
     */
    public void setScaleY( float p_s)
      {
      m_yy = p_s ;
      }

    /**
     * Initialisation de la matrice de changement d'echelle Z.
     */
    public void setScaleZ( float p_s)
      {
      m_zz = p_s ;
      }
 }


