
namespace XELF.Framework {

	public partial struct Matrix {
		/// <summary>
		/// ビュー行列を作る。
		/// </summary>
		/// <param name="cameraPosition"></param>
		/// <param name="cameraTarget"></param>
		/// <param name="cameraUpVector"></param>
		/// <param name="result"></param>
		public static void CreateLookAt(ref Vector3 cameraPosition, ref Vector3 cameraTarget, ref Vector3 cameraUpVector,
			out Matrix result) {
			Vector3 direction;
			Vector3.Subtract(ref cameraPosition, ref cameraTarget, out direction);
			direction.Normalize();
			cameraUpVector.Normalize();
			Vector3 right;
			Vector3.Cross(ref cameraUpVector, ref direction, out right);
			right.Normalize();
			Vector3.Cross(ref direction, ref right, out cameraUpVector);
			cameraUpVector.Normalize();
			result = new Matrix(
				right.X, cameraUpVector.X, direction.X, 0,
				right.Y, cameraUpVector.Y, direction.Y, 0,
				right.Z, cameraUpVector.Z, direction.Z, 0,
				0, 0, 0, 1);
			Vector4 position = new Vector4(cameraPosition, 1);
			Vector4 translation;
			Vector4.TransformCoordinate(ref position, ref result, out translation);
			result.M41 = -translation.X;
			result.M42 = -translation.Y;
			result.M43 = -translation.Z;
			result.M44 = -translation.W;
		}
		/// <summary>
		/// ビュー行列を作る。
		/// </summary>
		/// <param name="cameraPosition"></param>
		/// <param name="cameraTarget"></param>
		/// <param name="cameraUpVector"></param>
		/// <returns></returns>
		public static Matrix CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) {
			Matrix result;
			CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector, out result);
			return result;
		}
	}

}
