text: /*global CANNON:true */
  
  /**
   * @class CANNON.Vec3
   * @brief 3-dimensional vector
   * @param float x
   * @param float y
   * @param float z
   * @author schteppe
   */
  CANNON.Vec3 = function(x,y,z){
      /**
      * @property float x
      * @memberof CANNON.Vec3
      */
      this.x = x||0.0;
      /**
      * @property float y
      * @memberof CANNON.Vec3
      */
      this.y = y||0.0;
      /**
      * @property float z
      * @memberof CANNON.Vec3
      */
      this.z = z||0.0;
  };
  
  /**
   * @method cross
   * @memberof CANNON.Vec3
   * @brief Vector cross product
   * @param CANNON.Vec3 v
   * @param CANNON.Vec3 target Optional. Target to save in.
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.cross = function(v,target){
      var vx=v.x, vy=v.y, vz=v.z, x=this.x, y=this.y, z=this.z;
      target = target || new CANNON.Vec3();
  
      var A = [this.x, this.y, this.z];
      var B = [v.x, v.y, v.z];
      
      /*target.x = (A[1] * B[2]) - (A[2] * B[1]);
      target.y = (A[2] * B[0]) - (A[0] * B[2]);
      target.z = (A[0] * B[1]) - (A[1] * B[0]);*/
      target.x = (y * vz) - (z * vy);
      target.y = (z * vx) - (x * vz);
      target.z = (x * vy) - (y * vx);
      
      return target;
  };
  
  /**
   * @method set
   * @memberof CANNON.Vec3
   * @brief Set the vectors' 3 elements
   * @param float x
   * @param float y
   * @param float z
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.set = function(x,y,z){
      this.x = x;
      this.y = y;
      this.z = z;
      return this;
  };
      
  /**
   * @method vadd
   * @memberof CANNON.Vec3
   * @brief Vector addition
   * @param CANNON.Vec3 v
   * @param CANNON.Vec3 target Optional.
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.vadd = function(v,target){
      if(target){
          target.x = v.x + this.x;
          target.y = v.y + this.y;
          target.z = v.z + this.z;
      } else {
          return new CANNON.Vec3(this.x + v.x,
                                 this.y + v.y,
                                 this.z + v.z);
      }  
  };
      
  /**
   * @method vsub
   * @memberof CANNON.Vec3
   * @brief Vector subtraction
   * @param CANNON.Vec3 v
   * @param CANNON.Vec3 target Optional. Target to save in.
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.vsub = function(v,target){
      if(target){
          target.x = this.x - v.x;
          target.y = this.y - v.y;
          target.z = this.z - v.z;
      } else {
          return new CANNON.Vec3(this.x-v.x,
                                 this.y-v.y,
                                 this.z-v.z);
      }
  };
  
  /**
   * @method crossmat
   * @memberof CANNON.Vec3
   * @brief Get the cross product matrix a_cross from a vector, such that a x b = a_cross * b = c
   * @see http://www8.cs.umu.se/kurser/TDBD24/VT06/lectures/Lecture6.pdf
   * @return CANNON.Mat3
   */
  CANNON.Vec3.prototype.crossmat = function(){
      return new CANNON.Mat3([     0,  -this.z,   this.y,
                              this.z,        0,  -this.x,
                             -this.y,   this.x,        0]);
  };
  
  /**
   * @method normalize
   * @memberof CANNON.Vec3
   * @brief Normalize the vector. Note that this changes the values in the vector.
   * @return float Returns the norm of the vector
   */
  CANNON.Vec3.prototype.normalize = function(){
      var x=this.x, y=this.y, z=this.z;
      var n = Math.sqrt(x*x + y*y + z*z);
      if(n>0.0){
          var invN = 1/n;
          this.x *= invN;
          this.y *= invN;
          this.z *= invN;
      } else {
          // Make something up
          this.x = 0;
          this.y = 0;
          this.z = 0;
      }
      return n;
  };
  
  /**
   * @method unit
   * @memberof CANNON.Vec3
   * @brief Get the version of this vector that is of length 1.
   * @param CANNON.Vec3 target Optional target to save in
   * @return CANNON.Vec3 Returns the unit vector
   */
  CANNON.Vec3.prototype.unit = function(target){
      target = target || new CANNON.Vec3();
      var x=this.x, y=this.y, z=this.z;
      var ninv = Math.sqrt(x*x + y*y + z*z);
      if(ninv>0.0){
          ninv = 1.0/ninv;
          target.x = x * ninv;
          target.y = y * ninv;
          target.z = z * ninv;
      } else {
          target.x = 0;
          target.y = 0;
          target.z = 0;
      }
      return target;
  };
  
  /**
   * @method norm
   * @memberof CANNON.Vec3
   * @brief Get the 2-norm (length) of the vector
   * @return float
   */
  CANNON.Vec3.prototype.norm = function(){
      var x=this.x, y=this.y, z=this.z;
      return Math.sqrt(x*x + y*y + z*z);
  };
  
  /**
   * @method norm2
   * @memberof CANNON.Vec3
   * @brief Get the squared length of the vector
   * @return float
   */
  CANNON.Vec3.prototype.norm2 = function(){
      return this.dot(this);
  };
  
  CANNON.Vec3.prototype.distanceTo = function(p){
      var x=this.x, y=this.y, z=this.z;
      var px=p.x, py=p.y, pz=p.z;
      return Math.sqrt((px-x)*(px-x)+
                       (py-y)*(py-y)+
                       (pz-z)*(pz-z));
  };
  
  /**
   * @method mult
   * @memberof CANNON.Vec3
   * @brief Multiply the vector with a scalar
   * @param float scalar
   * @param CANNON.Vec3 target
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.mult = function(scalar,target){
      if(!target)
          target = new CANNON.Vec3();
      target.x = scalar*this.x;
      target.y = scalar*this.y;
      target.z = scalar*this.z;
      return target;
  };
  
  /**
   * @method dot
   * @memberof CANNON.Vec3
   * @brief Calculate dot product
   * @param CANNON.Vec3 v
   * @return float
   */
  CANNON.Vec3.prototype.dot = function(v){
      return (this.x * v.x + this.y * v.y + this.z * v.z);
  };
  
  /**
   * @method isZero
   * @memberof CANNON.Vec3
   * @return bool
   */
  CANNON.Vec3.prototype.isZero = function(){
      return this.x===0 && this.y===0 && this.z===0;
  }
  
  /**
   * @method negate
   * @memberof CANNON.Vec3
   * @brief Make the vector point in the opposite direction.
   * @param CANNON.Vec3 target Optional target to save in
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.negate = function(target){
      target = target || new CANNON.Vec3();
      target.x = -this.x;
      target.y = -this.y;
      target.z = -this.z;
      return target;
  };
  
  /**
   * @method tangents
   * @memberof CANNON.Vec3
   * @brief Compute two artificial tangents to the vector
   * @param CANNON.Vec3 t1 Vector object to save the first tangent in
   * @param CANNON.Vec3 t2 Vector object to save the second tangent in
   */
  CANNON.Vec3.prototype.tangents = function(t1,t2){
      var norm = this.norm();
      if(norm>0.0){
          var n = new CANNON.Vec3(this.x/norm,
                                  this.y/norm,
                                  this.z/norm);
          if(n.x<0.9){
              var rand = Math.random();
              n.cross(new CANNON.Vec3(rand,0.0000001,0).unit(),t1);
          } else
              n.cross(new CANNON.Vec3(0.0000001,rand,0).unit(),t1);
          n.cross(t1,t2);
      } else {
          // The normal length is zero, make something up
          t1.set(1,0,0).normalize();
          t2.set(0,1,0).normalize();
      }
  };
  
  /**
   * @method toString
   * @memberof CANNON.Vec3
   * @brief Converts to a more readable format
   * @return string
   */
  CANNON.Vec3.prototype.toString = function(){
      return this.x+","+this.y+","+this.z;
  };
  
  /**
   * @method copy
   * @memberof CANNON.Vec3
   * @brief Copy the vector.
   * @param CANNON.Vec3 target
   * @return CANNON.Vec3
   */
  CANNON.Vec3.prototype.copy = function(target){
      target = target || new CANNON.Vec3();
      target.x = this.x;
      target.y = this.y;
      target.z = this.z;
      return target;
  };
  
  
  /**
   * @method lerp
   * @memberof CANNON.Vec3
   * @brief Do a linear interpolation between two vectors
   * @param CANNON.Vec3 v
   * @param float t A number between 0 and 1. 0 will make this function return u, and 1 will make it return v. Numbers in between will generate a vector in between them.
   * @param CANNON.Vec3 target
   */
  CANNON.Vec3.prototype.lerp = function(v,t,target){
      var x=this.x, y=this.y, z=this.z;
      target.x = x + (v.x-x)*t;
      target.y = y + (v.y-y)*t;
      target.z = z + (v.z-z)*t;
  };
  
  /**
   * @method almostEquals
   * @memberof CANNON.Vec3
   * @brief Check if a vector equals is almost equal to another one.
   * @param CANNON.Vec3 v
   * @param float precision
   * @return bool
   */
  CANNON.Vec3.prototype.almostEquals = function(v,precision){
      if(precision===undefined)
          precision = 1e-6;
      if( Math.abs(this.x-v.x)>precision ||
          Math.abs(this.y-v.y)>precision ||
          Math.abs(this.z-v.z)>precision)
          return false;
      return true;
  }
  
  /**
   * @method almostZero
   * @brief Check if a vector is almost zero
   * @param float precision
   * @memberof CANNON.Vec3
   */
  CANNON.Vec3.prototype.almostZero = function(precision){
      if(precision===undefined)
          precision = 1e-6;
      if( Math.abs(this.x)>precision ||
          Math.abs(this.y)>precision ||
          Math.abs(this.z)>precision)
          return false;
      return true;
  }