// This is vector.cc CVS version: $Id: vector.cc,v 1.2 2000/02/28 18:06:24 andreaha Exp $
#include "eng.h"

/************************************************************************/
/* World::Vector                                                        */
/************************************************************************/

/* vector constructors */
World::Vector::Vector() {
  dpush1("World::Vector::Vector()");

  dpop();
}

World::Vector::Vector(float a, float b, float c) {
  dpush4("World::Vector::Vector(%3.1f, %3.1f, %3.1f)",a,b,c);

  x = a;
  y = b;
  z = c;

  dpop();
}

/* print out vector */
void World::Vector::printOut() {
  dpush1("World::Vector::printOut()");

  print2("Vector [%#010x] printout:\n", (int)this);
  print4("  [ %6.2f %6.2f %6.2f ]\n", x, y, z);

  dpop();
}

/* reset Vector */
void World::Vector::reset() {
  dpush1("World::Vector::reset()");

  x = y = z = 0.0;

  dpop();
}

/* set values */
void World::Vector::set(float a, float b, float c) {
  dpush4("World::Vector::set(%3.1f,%3.1f,%3.1f)",a,b,c);

  x = a;
  y = b;
  z = c;

  dpop();
}
void World::Vector::set(World::Vector *v) {
  dpush2("World::Vector::set(%#010x)",(int)v);

  x = v->x;
  y = v->y;
  z = v->z;

  dpop();
}

/* add values */
void World::Vector::add(float a, float b, float c) {
  dpush4("World::Vector::add(%3.1f,%3.1f,%3.1f)",a,b,c);

  x += a;
  y += b;
  z += c;

  dpop();
}
void World::Vector::add(World::Vector *v) {
  dpush2("World::Vector::add(%#010x)",(int)v);

  x += v->x;
  y += v->y;
  z += v->z;

  dpop();
}

/* sub values */
void World::Vector::sub(float a, float b, float c) {
  dpush4("World::Vector::sub(%3.1f,%3.1f,%3.1f)",a,b,c);

  x -= a;
  y -= b;
  z -= c;

  dpop();
}
void World::Vector::sub(World::Vector *v) {
  dpush2("World::Vector::sub(%#010x)",(int)v);

  x -= v->x;
  y -= v->y;
  z -= v->z;

  dpop();
}

/* mul values */
void World::Vector::mult(float n) {
  dpush2("World::Vector::mult(%3.1f)",n);

  x *= n;
  y *= n;
  z *= n;

  dpop();
}

/* cross vector with (x,y,z) */
void World::Vector::crossWith(float a, float b, float c) {
  dpush4("World::Vector::crossWith(%3.1f,%3.1f,%3.1f)",a,b,c);

  float nx, ny, nz;

  nx = (y * c) - (z * b);
  ny = (z * a) - (x * c);
  nz = (x * b) - (y * a);

  set(nx, ny, nz);

  dpop();
}
void World::Vector::crossWith(World::Vector *v) {
  dpush2("World::Vector::crossWith(%#010x)",(int)v);

  float nx, ny, nz;

  nx = (y * v->z) - (z * v->y);
  ny = (z * v->x) - (x * v->z);
  nz = (x * v->y) - (y * v->x);

  set(nx, ny, nz);

  dpop();
}

/* dot vector with (x,y,z) */
float World::Vector::dotWith(float a, float b, float c) {
  dpush4("World::Vector::dotWith(%3.1f,%3.1f,%3.1f)",a,b,c);

  dpop();
  return ((x*a) + (y*b) + (z*c));
}
float World::Vector::dotWith(Vector *v) {
  dpush2("World::Vector::dotWith(%#010x)",(int)v);

  dpop();
  return ((x*v->x) + (y*v->y) + (z*v->z));
}

/* set length = 1.0 */
void World::Vector::normalize() {
  dpush1("World::Vector::normalize()");

  float len = sqrt((x*x) + (y*y) + (z*z));
  if (len == 0) {
    len = 0;
  } else {
    len = 1.0 / len;
  }

  x *= len;
  y *= len;
  z *= len;
 
  dpop();
}

/* return length */
float World::Vector::length() {
  dpush1("World::Vector::length()");

  dpop();
  return sqrt((x*x) + (y*y) + (z*z));
}

/* + operator override */
World::Vector World::Vector::operator +(const Vector &v) const {
  dpush2("World::Vector::operator +(%#010x) const",(int)&v);

  dpop();
  return World::Vector(x + v.x, y + v.y, z + v.z);
}

/* - operator override */
World::Vector World::Vector::operator -(const Vector &v) const {
  dpush2("World::Vector::operator -(%#010x) const",(int)&v);

  dpop();
  return World::Vector(x - v.x, y - v.y, z - v.z);
}

/* dot operator override */
/*
float Vector::operator dot(const Vector &v) const {

  dpush2("Vector::operator dot(%#010x) const",(int)v);

  dpop();
  return (x * v.x) + (y * v.y) + (z * v.z);
}
*/

/* cross operator override */
/*
Vector Vector::operator cross(const Vector &v) const {

  dpush2("Vector::operator cross(%#010x) const",(int)v);

  dpop();
  return Vector((y * v.z) - (z * v.y),
                (z * v.x) - (x * v.z),
                (x * v.y) - (y * v.x));
}
*/


/* + operator override */
World::Vector World::Vector::operator *(float f) const {
  dpush2("World::Vector::operator *(%3.1f) const",f);

  dpop();
  return World::Vector(x * f, y * f, z * f);
}

/* + operator override */
World::Vector World::Vector::operator /(float f) const {
  dpush2("World::Vector::operator /(%3.1f) const",f);
  float divlen = (float )1.0 / f;
  dpop();
  return World::Vector(x * divlen, y * divlen, z * divlen);
}


/* translate vector with matrix */
void World::Vector::genTransVect(World::Vector *v, World::Matrix *mmat) {
  dpush3("World::Vector::genTransVect(%#010x, %#010x)",(int)v,(int)mmat);

  float *m = mmat->m;

  x = v->x * m[ 0]
    + v->y * m[ 1]
    + v->z * m[ 2] + m[ 3];
  y = v->x * m[ 4]
    + v->y * m[ 5]
    + v->z * m[ 6] + m[ 7];
  z = v->x * m[ 8]
    + v->y * m[ 9]
    + v->z * m[10] + m[11];

  dpop();
}

/* generate transformation vector */
void World::Vector::genTransform(Matrix *mmat) {
  dpush2("World::Vector::genTransform(%#010x)",(int)mmat);

  float *n = mmat->m;
  float nx,ny,nz;

  nx = (x * n[0])
     + (y * n[1])
     + (z * n[2]) + n[3];
  ny = (x * n[4])
     + (y * n[5])
     + (z * n[6]) + n[7];
  nz = (x * n[8])
     + (y * n[9])
     + (z * n[10]) + n[11];

  set(nx, ny, nz);

  dpop();
}





