// basic vectors

function vec3(x, y, z)
{
	// the data
	this.x = x;
	this.y = y;
	this.z = z;
}

vec3.prototype.scale = function(s)
{
	this.x*=s;
	this.y*=s;
	this.z*=s;
}

vec3.prototype.getAsArray = function()
{
	return [ this.x, this.y, this.z ];
}

vec3.prototype.getAsWebGLFloatArray = function()
{
	return new WebGLFloatArray(this.getAsArray());
}

vec3.prototype.length = function()
{
     return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
}

vec3.prototype.lengthSqrd = function()
{
	return dotVec3(this, this);
}

vec3.prototype.normalize = function()
{
	length = this.length();
	if (length == 0) {
		// bad vector, just use something reasonable
		this.x = 0;
		this.y = 0;
		this.z = 1;
	} else if (length != 1) {
		this.x /= length;
		this.y /= length;
		this.z /= length;
	}
}

vec3.prototype.negate = function()
{
	this.x = -1*this.x;
	this.y = -1*this.y;
	this.z = -1*this.z;
}

function addVec3 (v1, v2)
{
	return new vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}

function subVec3(v1, v2)
{
	return new vec3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}

function dotVec3(v1, v2)
{
	return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}

function crossVec3(v1, v2)
{
	return new vec3( (v1.y*v2.z - v2.y*v1.z), -(v1.x*v2.z - v2.x*v1.z), (v1.x*v2.y - v2.x*v1.y) );
}

function lerpVec3(vecA, vecB, lambda)
{
	var b = subVec3(vecB, vecA);
	b.scale(lambda);
	return addVec3(vecA,  b);
}

function negateVec3(vec)
{
   var v = new vec3(vec.x, vec.y, vec. z);
   v.x = -1*vec.x;
   v.y = -1*vec.y;
   v.z = -1*vec.z;
   
   return v;
}

function scaleVec3(vec, scale)
{
   var v = new vec3(vec.x, vec.y, vec. z);
   v.x *= scale;
   v.y *= scale;
   v.z *= scale;
   
   return v;
}


function zeroVec()
{
	return new vec3(0,0,0);
}

function rightVec()
{
	return new vec3(1,0,0);
}

function upVec()
{
	return new vec3(0,1,0);
}

function lookVec()
{
	return new vec3(0,0,1);
}

function vec4(x, y, z, w)
{
	// the data
	this.x = x;
	this.y = y;
	this.z = z;
	this.w = w;
}
