/** \defgroup Rendering Rendering classes */

/** @addtogroup Rendering
    @{
*/

/** @file CVectBase.cpp
    \brief This file contains the implementation of the CVectBase class.

    It contains the function that builds the base.  The first vector
    is simply a vector going from the eye of the viewer to the center
    of the bounding box of the surface.  The third one is obtained by
    substracting from the vector \f$ \vec{k} \f$ the component that is
    parallel to the first vector.  If the first vector is parallel to
    \f$ \vec{k} \f$, \f$ \vec{j} \f$ is taken instead.  The second
    vector is the cross product of the first one and the third one.
    Note that this base is not direct, meaning that
    \f$ \vec{B1} \times \vec{B2} = - \vec{B3} \f$
*/

#include <cmath>
#include <iostream>

#include "popassert.h"
#include "CVector3f.h"
#include "CVectBase.h"



/**
   This constructor does not calculate the vectors of the base.
*/
CVectBase::CVectBase() : m_ViewerPos(0,0,0), m_BoxPos(0,0,0)
{
  m_Radius = -1;
}


/**
   This constructor calculates the vectors of the base.
*/
CVectBase::CVectBase(const CVector3f& viewerpos,
                     const CVector3f& boxpos,
                     float radius, bool update) :
  m_ViewerPos(viewerpos), m_BoxPos(boxpos)
{
  // Radius
  m_Radius = radius;

  if (update)
    Update();
}


/**
   This is the function that builds the base.

   The first vector is simply a vector going from the eye of the
   viewer to the center of the bounding box of the surface.  The
   third one is obtained by substracting from the vector \f$ \vec{k}
   \f$ the component that is parallel to the first vector.  If the
   first vector is parallel to \f$ \vec{k} \f$, \f$ \vec{j} \f$ is
   taken instead.  The second vector is the cross product of the
   first one and the third one.  Note that this base is not direct,
   meaning that \f$ \vec{B1} \times \vec{B2} = - \vec{B3} \f$
*/
void CVectBase::Update(void)
{
  // First vector
  m_B1 = m_BoxPos - m_ViewerPos;

  // Third vector
  if (m_B1.x == 0 && m_B1.y == 0)
    {
      m_B3 = CVector3f(0, 1, 0);
    }
  else
    {
      m_B3 = CVector3f(0, 0, 1) - (CVector3f(0, 0, 1) >> m_B1);
      m_B3.Normalize();
    }

  // Second vector
  m_B2 = m_B1 ^ m_B3;
  m_B2.Normalize();
}

/** @} */
