text: #pragma once
  
  namespace Volund
  {
  	/// <summary>
  	/// X, Y
  	/// </summary>
  	typedef glm::vec2 Vec2;
  
  	/// <summary>
  	/// X, Y (Uses int)
  	/// </summary>
  	typedef glm::ivec2 IVec2;
  
  	/// <summary>
  	/// X, Y (Uses double)
  	/// </summary>
  	typedef glm::dvec2 DVec2;
  
  	/// <summary>
  	/// X, Y, Z
  	/// </summary>
  	typedef glm::vec3 Vec3;
  
  	/// <summary>
  	/// X, Y, Z (Uses int)
  	/// </summary>
  	typedef glm::ivec3 IVec3;
  
  	/// <summary>
  	/// X, Y, Z (Uses double)
  	/// </summary>
  	typedef glm::dvec3 DVec3;
  
  	/// <summary>
  	/// X, Y, Z, W
  	/// </summary>
  	typedef glm::vec4 Vec4;
  
  	/// <summary>
  	/// X, Y, Z, W (Uses int)
  	/// </summary>
  	typedef glm::ivec4 IVec4;
  
  	/// <summary>
  	/// X, Y, Z, W (Uses double)
  	/// </summary>
  	typedef glm::dvec4 DVec4;
  
  	/// <summary>
  	/// 3x3 matrix
  	/// </summary>
  	typedef glm::mat3 Mat3;
  
  	/// <summary>
  	/// 4x4 matrix
  	/// </summary>
  	typedef glm::mat4 Mat4;
  
  	/// <summary>
  	/// Quaternion
  	/// </summary>
  	typedef glm::quat Quat;
  
  	/// <summary>
  	/// Red, Green, Blue, (Same as a Vec3)
  	/// </summary>
  	typedef glm::vec3 RGBV;
  
  	/// <summary>
  	/// Red, Green, Blue, Alpha (Same as a Vec4)
  	/// </summary>
  	typedef glm::vec4 RGBA;
  
  	/// <summary>
  	/// Stores mathematical functions.
  	/// </summary>
  	namespace Math
  	{
  		/// <summary>
  		/// Pi
  		/// </summary>
  		const float PI = 3.14159265359f;
  
  		/// <summary>
  		/// A vector pointing up.
  		/// </summary>
  		const Vec3 Up = Vec3(0, 1, 0);
  
  		/// <summary>
  		/// A vector pointing down.
  		/// </summary>
  		const Vec3 Down = Vec3(0, -1, 0);
  
  		/// <summary>
  		/// A vector pointing Forward.
  		/// </summary>
  		const Vec3 Forward = Vec3(0, 0, 1);
  
  		/// <summary>
  		/// A vector pointing Backward.
  		/// </summary>
  		const Vec3 Back = Vec3(0, 0, -1);
  
  		/// <summary>
  		/// A vector pointing Left.
  		/// </summary>
  		const Vec3 Left = Vec3(-1, 0, 0);
  
  		/// <summary>
  		/// A vector pointing Right.
  		/// </summary>
  		const Vec3 Right = Vec3(1, 0, 0);
  
  		/// <summary>
  		/// A vector filled with ones.
  		/// </summary>
  		const Vec3 One = Vec3(1, 1, 1);
  
  		/// <summary>
  		/// A vector filled with zeros.
  		/// </summary>
  		const Vec3 Zero = Vec3(0, 0, 0);
  
  		/// <summary>
  		/// Returns the distance from V1 to V2.
  		/// </summary>
  		float Distance(Vec3 const& V1, Vec3 const& V2);
  
  		/// <summary>
  		/// Returns the squared distance from V1 to V2.
  		/// </summary>
  		float SquaredDistance(Vec3 const& V1, Vec3 const& V2);
  
  		/// <summary>
  		/// Returns the distance from V1 to V2.
  		/// </summary>
  		float Distance(Vec2 const& V1, Vec2 const& V2);
  
  		/// <summary>
  		/// Returns the squared distance from V1 to V2.
  		/// </summary>
  		float SquaredDistance(Vec2 const& V1, Vec2 const& V2);
  
  		/// <summary>
  		/// Returns the length of V.
  		/// </summary>
  		float Length(Vec3 const& V);
  
  		/// <summary>
  		/// Returns the rotated point P around the Origin.
  		/// </summary>
  		Vec3 RotatePoint(Vec3 const& Origin, Vec3 const& Rotation, Vec3 const& P);
  
  		/// <summary>
  		/// Returns a normalized version of V, (Meaning that it has a length of 1).
  		/// </summary>
  		Vec3 Normalize(Vec3 const& V);
  
  		/// <summary>
  		/// Returns a normalized version of V, (Meaning that it has a length of 1).
  		/// </summary>
  		Vec2 Normalize(Vec2 const& V);
  
  		/// <summary>
  		/// Returns a direction from the Origin to P.
  		/// </summary>
  		Vec3 LookAt(Vec3 const& Origin, Vec3 const& P);
  
  		/// <summary>
  		/// Returns the cross product of the vectors.
  		/// </summary>
  		Vec3 Cross(Vec3 const& S1, Vec3 const& S2);
  
  		/// <summary>
  		/// Returns the dot product of the vectors.
  		/// </summary>
  		float Dot(Vec3 const& V1, Vec3 const& V2);
  
  		/// <summary>
  		/// Returns the dot product of the vectors.
  		/// </summary>
  		float Dot(Vec4 const& V1, Vec4 const& V2);
  
  		/// <summary>
  		/// Returns the dot product of the vectors.
  		/// </summary>
  		float Dot(Vec2 const& V1, Vec2 const& V2);
  
  		/// <summary>
  		/// Returns a direction from the Origin to P.
  		/// </summary>
  		Vec2 LookAt(Vec2 const& Origin, Vec2 const& P);
  
  		/// <summary>
  		/// Reflects the indicent vector I using the normal vector N.
  		/// </summary>
  		Vec3 Reflect(Vec3 const& I, Vec3 const& N);
  
  		/// <summary>
  		/// Returns the absolute vector of the supplied vector, (Meaning that all components of the vector are positive).
  		/// </summary>
  		Vec3 Abs(Vec3 const& V);
  
  		/// <summary>
  		/// Returns the angle from V1 to V2.
  		/// </summary>
  		float Angle2D(Vec2 const& V1, Vec2 const& V2);
  
  		/// <summary>
  		/// Returns the sign of the elements of vector X, (If a component is negative it returns -1, if its positive it returns 1 and if neither it returns 0).
  		/// </summary>
  		Vec3 Sign(Vec3 const& X);
  	
  		/// <summary>
  		/// Returns the vector of degrees as a vector of radians.
  		/// </summary>
  		Vec3 ToRadians(Vec3 const& V);
  
  		/// <summary>
  		/// Returns the vector of radians as a vector of degrees.
  		/// </summary>
  		Vec3 ToDegrees(Vec3 const& V);
  
  		/// <summary>
  		/// Return the angle of Q.
  		/// </summary>
  		float Angle(Quat const& Q);
  
  		/// <summary>
  		/// Returns the axis of Q.
  		/// </summary>
  		Vec3 Axis(Quat const& Q);
  
  		/// <summary>
  		/// Returns the cross product of Q1 and Q2.
  		/// </summary>
  		Quat Cross(Quat const& Q1, Quat const& Q2);
  
  		/// <summary>
  		/// Returns Q rotated by the supplied Angles.
  		/// </summary>
  		Quat QuaternionRotate(Quat const& Q, Vec3 const& Angles);
  
  		/// <summary>
  		/// Returns Q rotated by the supplied angle in the supplied axis.
  		/// </summary>
  		Quat QuaternionAxis(float Angle, Vec3 const& Axis);
  
  		/// <summary>
  		/// Returns the euler angles converted to a quaternion.
  		/// </summary>
  		Quat Quaternion(Vec3 const& Angles);
  
  		/// <summary>
  		/// Returns Q as Euler angles.
  		/// </summary>
  		Vec3 Euler(Quat const& Q);
  
  		/// <summary>
  		/// Returns the conjugate of Q.
  		/// </summary>
  		Quat Conjugate(Quat const& Q);
  
  		/// <summary>
  		/// Returns the dot product of Q1 and Q2.
  		/// </summary>
  		float Dot(Quat const& Q1, Quat const& Q2);
  
  		/// <summary>
  		/// Returns the inverse of Q.
  		/// </summary>
  		Quat Inverse(Quat const& Q);
  
  		/// <summary>
  		/// Returns a lerped quaternion between the start and end quaternion where X is the fraction that decides how much of each quaternion to use.
  		/// </summary>
  		Quat Lerp(Quat const& Start, Quat const& End, float X);
  
  		/// <summary>
  		/// Returns a sphericly lerped quaternion between the start and end quaternion where X is the fraction that decides how much of each quaternion to use.
  		/// </summary>
  		Quat Slerp(Quat const& Start, Quat const& End, float X);
  
  		/// <summary>
  		/// Returns the length of Q.
  		/// </summary>
  		float Length(Quat const& Q);
  
  		/// <summary>
  		/// Returns a normalized version of Q, (Meaning that it has a length of 1).
  		/// </summary>
  		Quat Normalize(Quat const& Q);
  
  		/// <summary>
  		/// Returns a quaternion that looks from the Origin to P.
  		/// </summary>
  		Quat RotateTo(Vec3 const& Origin, Vec3 const& P);
  
  		/// <summary>
  		/// Returns if two floats are approximately equal within the given epsilon.
  		/// </summary>
  		bool Approximately(float N1, float N2, float epsilon = std::numeric_limits<float>::epsilon());
  
  		/// <summary>
  		/// Returns a random float between min and max.
  		/// </summary>
  		float Random_F(float Min, float Max);
  
  		/// <summary>
  		/// Returns a random int between min and max.
  		/// </summary>
  		int32_t Random_I(int32_t Min, int32_t Max);
  
  		/// <summary>
  		/// Seeds the random function with the current time.
  		/// </summary>
  		void SeedRandom();
  
  		/// <summary>
  		/// Returns the HSV as a RGB value.
  		/// </summary>
  		RGBV HSVtoRGB(float H, float S, float V);
  
  		/// <summary>
  		/// Returns the given angle in radians.
  		/// </summary>
  		float ToRadians(float Angle);
  
  		/// <summary>
  		/// Returns the given angle in degrees.
  		/// </summary>
  		float ToDegrees(float Angle);
  
  		/// <summary>
  		/// Returns the absolute value of X. (Meaning that its always positive).
  		/// </summary>	
  		float Abs(float X);
  
  		/// <summary>
  		/// Returns the Acos of X in radians.
  		/// </summary>	
  		float Acos(float X);
  
  		/// <summary>
  		/// Returns the Asin of X in radians.
  		/// </summary>
  		float Asin(float X);
  
  		/// <summary>
  		/// Returns the Atan of X in radians.
  		/// </summary>
  		float Atan(float X);
  
  		/// <summary>
  		/// Returns the cos of X in radians.
  		/// </summary>
  		float Cos(float X);
  
  		/// <summary>
  		/// Returns the sin of X in radians.
  		/// </summary>
  		float Sin(float X);
  
  		/// <summary>
  		/// Returns the tan of X in radians.
  		/// </summary>
  		float Tan(float X);
  
  		/// <summary>
  		/// Returns X to the power E.
  		/// </summary>
  		float Pow(float X, float E);
  
  		/// <summary>
  		/// Returns X to the power of the integer E. (E must be 1 or larger)
  		/// </summary>
  		float IntPow(float X, uint32_t E);
  
  		/// <summary>
  		/// Returns x rounded upward.
  		/// </summary>
  		float Ceil(float X);
  
  		/// <summary>
  		/// Returns the natural log of X.
  		/// </summary>
  		float Log(float X);
  
  		/// <summary>
  		/// Rounds x downward.
  		/// </summary>
  		float Floor(float X);
  
  		/// <summary>
  		/// Returns the closest power of two to X.
  		/// </summary>
  		float ClosestPowerOfTwo(float X);
  
  		/// <summary>
  		/// Returns the sqrt of X.
  		/// </summary>
  		float Sqrt(float X);
  
  		/// <summary>
  		/// Returns a lerped vector between the start and end vector where X is the fraction that decides how much of each vector to use.
  		/// </summary>
  		template<typename T>
  		T Lerp(T const& Start, T const& End, float X);
  
  		/// <summary>
  		/// Returns the clamped value n between the lower and upper values.
  		/// </summary>
  		float Clamp(float N, float Lower, float Upper);
  
  		/// <summary>
  		/// Returns the largest value of X and Y.
  		/// </summary>
  		float Max(float X, float Y);
  
  		/// <summary>
  		/// Returns the smallest value of X and Y.
  		/// </summary>
  		float Min(float X, float Y);
  
  		/// <summary>
  		/// Returns the sign of X. (If X is negative it returns -1, if its positive it returns 1 and if neither returns 0).
  		/// </summary>
  		bool Sign(float X);
  
  	} //namespace Math
  
  	template<typename T>
  	T Math::Lerp(T const& Start, T const& End, float X)
  	{
  		return End * (1.f - X) + Start * X;
  	}
  
  } //namespace Volund