#ifndef ___VECTOR3D

#define ___VECTOR3D

#include <math.h>

struct Vector3D
{

  Vector3D() {};
  Vector3D( const float* pf) 
  {
    x=pf[0]; y=pf[1]; z=pf[2];
  }

  Vector3D( float _x, float _y, float _z)
  {
    x=_x;
    y=_y;
    z=_z;
  }

  static Vector3D ZERO;


  // casting
  operator float* ()
  {
    return (&x);
  }
  operator const float* () const
  {
    return (&x);
  }

  // assignment operators
  Vector3D& operator += ( const Vector3D& v3d)
  {
    x+=v3d.x;
    y+=v3d.y;
    z+=v3d.z;

    return (*this);
  }

  Vector3D& operator -= ( const Vector3D& v3d)
  {
    x-=v3d.x;
    y-=v3d.y;
    z-=v3d.z;

    return (*this);
  }

  Vector3D& operator *= ( float f)
  {
    x*=f;
    y*=f;
    z*=f;

    return (*this);
  }

  Vector3D& operator /= ( float f)
  {
    x/=f;
    y/=f;
    z/=f;

    return (*this);
  }

  float Length() const
  {
    return (sqrtf(x*x+y*y+z*z));
  }

  float SquaredLength() const
  {
    return (x*x+y*y+z*z);
  }

  Vector3D& Normalize()
  {
    float oof=1.0f/Length();
    x*=oof;
    y*=oof;
    z*=oof;

    return (*this);
  }

  // unary operators
  Vector3D operator + () const
  {
    Vector3D v(x,y,z);
    return (v);
  }

  Vector3D operator - () const
  {
    Vector3D v(-x,-y,-z);
    return (v);
  }

  static float Dot(const Vector3D& vA, const Vector3D& vB)
  {
    return (vA.x*vB.x+vA.y*vB.y+vA.z*vB.z);
  }

  static Vector3D Cross(const Vector3D& vA, const Vector3D& vB)
  {
    Vector3D v3d;

    v3d.x=vA.y*vB.z-vA.z*vB.y;
    v3d.y=vA.z*vB.x-vA.x*vB.z;
    v3d.z=vA.x*vB.y-vA.y*vB.x;

    return (v3d);
  }

  float Dot(const Vector3D& vA)
  {
    return (Dot(*this, vA));
  }

  Vector3D Cross(const Vector3D& vA)
  {
    return (Cross(*this, vA));
  }

  // binary operators
  Vector3D operator+( const Vector3D& v) const
  {
    Vector3D r(x+v.x,y+v.y,z+v.z);
    return (r);
  }

  Vector3D operator-( const Vector3D& v) const
  {
    Vector3D r(x-v.x,y-v.y,z-v.z);
    return (r);
  }

  Vector3D operator*( float f) const
  {
    Vector3D v(x*f,y*f,z*f);
    return (v);
  }

  Vector3D operator/( float f) const
  {
    Vector3D v(x/f,y/f,z/f);
    return (v);
  }

  friend Vector3D operator * ( float f, const Vector3D& v)
  {
    Vector3D r(v.x*f,v.y*f,v.z*f);
    return (r);
  }

  bool operator == ( const Vector3D& v) const
  {
    return (x==v.x && y==v.y && z==v.z);
  }

  bool operator != ( const Vector3D& v) const
  {
    return (x!=v.x || y!=v.y || z!=v.z);
  }

  float x,y,z;
};



#endif
