
namespace XELF.Framework {

	public partial struct Vector2 {
		/// <summary>
		/// 変換してW=1に投影する。
		/// </summary>
		/// <param name="position"></param>
		/// <param name="matrix"></param>
		/// <param name="result"></param>
		public static void TransformCoordinate(ref Vector2 position, ref Matrix matrix, out Vector2 result) {
			result = new Vector2();
			result.X = position.X * matrix.M11 + position.Y * matrix.M31 + matrix.M41;
			result.Y = position.X * matrix.M12 + position.Y * matrix.M32 + matrix.M42;
			float w = position.X * matrix.M14 + position.Y * matrix.M34 + matrix.M44;
			Vector2.Multiply(ref result, MathHelper.Rcp(w), out result);
		}
		/// <summary>
		/// 変換してW=1に投影する。
		/// </summary>
		/// <param name="position"></param>
		/// <param name="matrix"></param>
		/// <returns></returns>
		public static Vector2 TransformCoordinate(Vector2 position, Matrix matrix) {
			Vector2 result;
			TransformCoordinate(ref position, ref matrix, out result);
			return result;
		}
	}

	public partial struct Vector3 {
		/// <summary>
		/// 変換してW=1に投影する。
		/// </summary>
		/// <param name="position"></param>
		/// <param name="matrix"></param>
		/// <param name="result"></param>
		public static void TransformCoordinate(ref Vector3 position, ref Matrix matrix, out Vector3 result) {
			result = new Vector3();
			result.X = position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31 + matrix.M41;
			result.Y = position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32 + matrix.M42;
			result.Z = position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33 + matrix.M43;
			float w = position.X * matrix.M14 + position.Y * matrix.M24 + position.Z * matrix.M34 + matrix.M44;
			Vector3.Multiply(ref result, MathHelper.Rcp(w), out result);
		}
		/// <summary>
		/// 変換してW=1に投影する。
		/// </summary>
		/// <param name="position"></param>
		/// <param name="matrix"></param>
		/// <returns></returns>
		public static Vector3 TransformCoordinate(Vector3 position, Matrix matrix) {
			Vector3 result;
			TransformCoordinate(ref position, ref matrix, out result);
			return result;
		}
	}

	public partial struct Vector4 {
		/// <summary>
		/// 変換してW=1に投影する。
		/// </summary>
		/// <param name="position"></param>
		/// <param name="matrix"></param>
		/// <param name="result"></param>
		public static void TransformCoordinate(ref Vector4 position, ref Matrix matrix, out Vector4 result) {
			result = new Vector4();
			result.X = position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31 + matrix.M41;
			result.Y = position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32 + matrix.M42;
			result.Z = position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33 + matrix.M43;
			result.W = position.X * matrix.M14 + position.Y * matrix.M24 + position.Z * matrix.M34 + matrix.M44;
		}
		/// <summary>
		/// 変換してW=1に投影する。
		/// </summary>
		/// <param name="position"></param>
		/// <param name="matrix"></param>
		/// <returns></returns>
		public static Vector4 TransformCoordinate(Vector4 position, Matrix matrix) {
			Vector4 result;
			TransformCoordinate(ref position, ref matrix, out result);
			return result;
		}
	}

}
