#include "SM_MathPCH.h"
#include <math.h>

#define PI 3.1415926535897932384626433832795f

Viewport::Viewport()
{
}

Viewport::Viewport(const    Vector3D& v3dPosition, 
                       const    Quaternion& qRotation,
                       float    fFOV,
                       float    fAspectRatio,
                       float    fZNear,
                       float    fZFar)
{
  Set(v3dPosition, qRotation, fFOV, fAspectRatio, fZNear, fZFar);
}

void Viewport::Set    (const    Vector3D&   v3dPosition, 
             const    Quaternion& qRotation,
             float    fFOV,
             float    fAspectRatio,
             float    fZNear,
             float    fZFar)
{
  m_v3dPosition =v3dPosition;
  m_qRotation   =qRotation;
  m_fFOV        =fFOV;
  m_fAspectRatio=fAspectRatio,
  m_fZNear      =fZNear;
  m_fZFar       =fZFar;  
}

void  Viewport::Set(const    Vector3D&   pos, 
                    const    Vector3D&   at,
                    const    Vector3D&   up,
                    float    fFOV,
                    float    fAspectRatio,
                    float    fZNear,
                    float    fZFar)
{

  Vector3D zaxis = at - pos; zaxis.Normalize();
  Vector3D xaxis = Vector3D::Cross(up, zaxis); xaxis.Normalize();
  Vector3D yaxis = Vector3D::Cross(zaxis, xaxis);

  Quaternion q;
  q.FromFrame(zaxis, yaxis, xaxis);
  
  Set(pos, q.Inverse(), fFOV, fAspectRatio, fZNear, fZFar);
}


void Viewport::InverseViewMatrix   (Matrix4X4& m) const
{
  ToTransform(&m, &m_v3dPosition, &m_qRotation);
}
  
void Viewport::ViewMatrix(Matrix4X4& m) const
{
  ToInverseTransform(&m, &m_v3dPosition, &m_qRotation);
}

void Viewport::ProjectionMatrix(Matrix4X4& m) const
{
  
  float w=1.0f/tanf(PI*m_fFOV/360.0f);
  float h=w/m_fAspectRatio;

  float fFar  = 1000000.0;
  float fNear = m_fZNear;
  //float fFar  = m_fZFar;
  //float fNear = m_fZNear;

  float Q=fFar/(fFar-fNear);


/*
  m.m_11=w   ; m.m_12=0.0f; m.m_13=0.0f         ; m.m_14=0.0f;
  m.m_21=0.0f; m.m_22=h   ; m.m_23=0.0f         ; m.m_24=0.0f;
  m.m_31=0.0f; m.m_32=0.0f; m.m_33=Q            ; m.m_34=1.0f;
  m.m_41=0.0f; m.m_42=0.0f; m.m_43=-Q*m_fZNear  ; m.m_44=0.0f;
  */

  m.m_11=w   ; m.m_12=0.0f; m.m_13=0.0f         ; m.m_14=0.0f;
  m.m_21=0.0f; m.m_22=h   ; m.m_23=0.0f         ; m.m_24=0.0f;
  m.m_31=0.0f; m.m_32=0.0f; m.m_33=Q            ; m.m_34=1.0f;
  m.m_41=0.0f; m.m_42=0.0f; m.m_43=-Q*fNear     ; m.m_44=0.0f;
}

  