/*
   Class Name:

      CVector3.

   Created by:

      Allen Sherrod (Programming Ace of www.UltimateGameProgramming.com).

   Description:

      This class represents a 3D point for a vertex's x, y, and z axis.
*/


#include"CVector.h"        // CVector3 class.


CVector3::CVector3()
{
   // Initialize the variables to 0.
   x = y = z = 0.0;
   nx = ny = nz = 0.0;
}


CVector3::CVector3(float X, float Y, float Z)
{
   // Initialize the varibles to the data in X, Y, and Z.
   x = X;
   y = Y;
   z = Z;
   nx = ny = nz = 0.0;
}


CVector3::CVector3(const CVector3 &v)
{
   // Initialize this object to v.
   x = v.x;
   y = v.y;
   z = v.z;
   nx = v.nx;
   ny = v.ny;
   nz = v.nz;
}


void CVector3::operator =(CVector3 v)
{
   // Make this objects x, y, and z equal to the object on the right of the = sign.
   x = v.x;
   y = v.y;
   z = v.z;
   nx = v.nx;
   ny = v.ny;
   nz = v.nz;
}


CVector3 CVector3::operator -(CVector3 v)
{
   // Return the value of this vector - v.
   return CVector3(x - v.x, y - v.y, z - v.z);
}


CVector3 CVector3::operator +(CVector3 v)
{
   // Return the value of this vector + v.
   return CVector3(x + v.x, y + v.y, z + v.z);
}


CVector3 CVector3::operator *(float f)
{
   // Return the value of this vector * f.
   return CVector3(x * f, y * f, z * f);
}


CVector3 CVector3::operator /(float f)
{
   // Return the value of this vector / f.  We do this by multiplying the recip.
   f = 1/f;

   return CVector3(x * f, y * f, z * f);
}


void CVector3::operator +=(CVector3 v)
{
   // Add this by object v and store results here.
   x += v.x;
   y += v.y;
   z += v.z;
}


void CVector3::operator -=(CVector3 v)
{
   // Subtract this by object v and store results here.
   x -= v.x;
   y -= v.y;
   z -= v.z;
}


void CVector3::operator *=(float f)
{
   // Multiply this by object f and store results here.
   x *= f;
   y *= f;
   z *= f;
}


void CVector3::operator /=(float f)
{
   // Divide this by object f and store results here by multiplying by the recip.
   f = 1/f;

   x *= f;
   y *= f;
   z *= f;
}


bool CVector3::operator ==(CVector3 v)
{
   // Return true if all equal each other, false if one or more don't.
   return ((x == v.x) && (y== v.y) && (z == v.z));
}


bool CVector3::operator !=(CVector3 v)
{
   // Return true if one or all don't equal each other, false if they equal.
   return !((x == v.x) && (y== v.y) && (z == v.z));
}


void CVector3::CrossProduct(CVector3 v1, CVector3 v2)
{
   // Get the cross product of v1 and v2 and store it in this vector.
   x = ((v1.y * v2.z) - (v1.z * v2.y));
   y = ((v1.z * v2.x) - (v1.x * v2.z));
   z = ((v1.x * v2.y) - (v1.y * v2.x));
}


float CVector3::DotProduct(CVector3 v1)
{
   // Get the dot product of v1 and this object and return it.
   return x * v1.x + y * v1.y + z * v1.z;
}


float CVector3::GetLength()
{
   // Return the length for this object.
   return (float)sqrt((x * x + y * y + z * z));
}


void CVector3::Normal()
{
   // Reduce this object to a unit vector.
   float lenght = GetLength();

   if(lenght == 0.0f)
      lenght = 1.0f;

   nx /= lenght;
   ny /= lenght;
   nz /= lenght;
}


void CVector3::Normalize(CVector3 Triangle[])
{
   // Normalize a triangle and store results in this object.
   CVector3 v1, v2;

   v1.x = Triangle[0].x - Triangle[1].x;
   v1.y = Triangle[0].y - Triangle[1].y;
   v1.z = Triangle[0].z - Triangle[1].z;

   v2.x = Triangle[1].x - Triangle[2].x;
   v2.y = Triangle[1].y - Triangle[2].y;
   v2.z = Triangle[1].z - Triangle[2].z;

   CrossProduct(v1, v2);
   Normal();
}


// Copyright March 2003
// All Rights Reserved!
// Allen Sherrod
// ProgrammingAce@UltimateGameProgramming.com
// www.UltimateGameProgramming.com