﻿
Matrix.prototype.M11 = 0;
Matrix.prototype.M12 = 0;
Matrix.prototype.M13 = 0;
Matrix.prototype.M14 = 0;
Matrix.prototype.M21 = 0;
Matrix.prototype.M22 = 0;
Matrix.prototype.M23 = 0;
Matrix.prototype.M24 = 0;
Matrix.prototype.M31 = 0;
Matrix.prototype.M32 = 0;
Matrix.prototype.M33 = 0;
Matrix.prototype.M34 = 0;
Matrix.prototype.M41 = 0;
Matrix.prototype.M42 = 0;
Matrix.prototype.M43 = 0;
Matrix.prototype.M44 = 0;
	
function Matrix()
{
	this.M11 = 1.0;
	this.M12 = 0.0;
	this.M13 = 0.0;
	this.M14 = 0.0;
	this.M21 = 0.0;
	this.M22 = 1.0;
	this.M23 = 0.0;
	this.M24 = 0.0;
	this.M31 = 0.0;
	this.M32 = 0.0;
	this.M33 = 1.0;
	this.M34 = 0.0;
	this.M41 = 0.0;
	this.M42 = 0.0;
	this.M43 = 0.0;
	this.M44 = 1.0;
}
	
Matrix.prototype.Multiply = function(mA)
{
	var m = new Matrix();
	m.M11 = this.M11 * mA.M11 + this.M12 * mA.M21 + this.M13 * mA.M31 + this.M14 * mA.M41;
	m.M12 = this.M11 * mA.M12 + this.M12 * mA.M22 + this.M13 * mA.M32 + this.M14 * mA.M42;
	m.M13 = this.M11 * mA.M13 + this.M12 * mA.M23 + this.M13 * mA.M33 + this.M14 * mA.M43;
	m.M14 = this.M11 * mA.M14 + this.M12 * mA.M24 + this.M13 * mA.M34 + this.M14 * mA.M44;
	
	m.M21 = this.M21 * mA.M11 + this.M22 * mA.M21 + this.M23 * mA.M31 + this.M24 * mA.M41;
	m.M22 = this.M21 * mA.M12 + this.M22 * mA.M22 + this.M23 * mA.M32 + this.M24 * mA.M42;
	m.M23 = this.M21 * mA.M13 + this.M22 * mA.M23 + this.M23 * mA.M33 + this.M24 * mA.M43;
	m.M24 = this.M21 * mA.M14 + this.M22 * mA.M24 + this.M23 * mA.M34 + this.M24 * mA.M44;
	
	m.M31 = this.M31 * mA.M11 + this.M32 * mA.M21 + this.M33 * mA.M31 + this.M34 * mA.M41;
	m.M32 = this.M31 * mA.M12 + this.M32 * mA.M22 + this.M33 * mA.M32 + this.M34 * mA.M42;
	m.M33 = this.M31 * mA.M13 + this.M32 * mA.M23 + this.M33 * mA.M33 + this.M34 * mA.M43;
	m.M34 = this.M31 * mA.M14 + this.M32 * mA.M24 + this.M33 * mA.M34 + this.M34 * mA.M44;
	
	m.M41 = this.M41 * mA.M11 + this.M42 * mA.M21 + this.M43 * mA.M31 + this.M44 * mA.M41;
	m.M42 = this.M41 * mA.M12 + this.M42 * mA.M22 + this.M43 * mA.M32 + this.M44 * mA.M42;
	m.M43 = this.M41 * mA.M13 + this.M42 * mA.M23 + this.M43 * mA.M33 + this.M44 * mA.M43;
	m.M44 = this.M41 * mA.M14 + this.M42 * mA.M24 + this.M43 * mA.M34 + this.M44 * mA.M44;
	
	return m;
}
	
function Matrix_RotationY(angle)
{
	var cosAngle = Math.cos(angle);
	var sinAngle = Math.sin(angle);
	var m = new Matrix();
	m.M11 = cosAngle;
	m.M13 = -sinAngle;
	m.M31 = sinAngle;
	m.M33 = cosAngle;
	return m;
}
	
function Matrix_PerspectiveFovLH(
	fieldOfView,
	aspectRatio,
	far,
	near
)
{
	var tanHalfFov = Math.tan(fieldOfView / 2);
	var yScale = 1 / tanHalfFov;
	var xScale = yScale / aspectRatio;
	
	var m = new Matrix();
	m.M11 = xScale;
	m.M22 = yScale;
	m.M33 = 1.0 - far / (far - near);
	m.M34 = 1.0;
	m.M43 = near * far / (far - near);
	m.M44 = 0;
	return m;
}
	
function Matrix_LookAt(vFrom, vAt, vWorldUp)
{
	var mat = new Matrix();
	
	var vView = new Vector3(0, 0, 0);
	vView.X = vAt.X - vFrom.X;
	vView.Y = vAt.Y - vFrom.Y;
	vView.Z = vAt.Z - vFrom.Z;

	vView.Normalize();

	var fDotProduct = Vector3_Dot( vWorldUp, vView );

	var vUp = new Vector3(0, 0, 0);
	vUp.X = vWorldUp.X - fDotProduct * vView.X;
	vUp.Y = vWorldUp.Y - fDotProduct * vView.Y;
	vUp.Z = vWorldUp.Z - fDotProduct * vView.Z;

	vUp.Normalize();

	var vRight = Vector3_Cross( vUp, vView );

	mat.M11 = vRight.X;
	mat.M12 = vUp.X;
	mat.M13 = vView.X;
	mat.M14 = 0;
	mat.M21 = vRight.Y;
	mat.M22 = vUp.Y;
	mat.M23 = vView.Y;
	mat.M24 = 0;
	mat.M31 = vRight.Z;
	mat.M32 = vUp.Z;
	mat.M33 = vView.Z;
	mat.M34 = 0;
	mat.M41 = - Vector3_Dot( vFrom, vRight );
	mat.M42 = - Vector3_Dot( vFrom, vUp );
	mat.M43 = - Vector3_Dot( vFrom, vView );
	mat.M44 = 1.0;

	return mat;
}

