1 #ifndef _UltimateOpenGL_Transform_h_
2 #define _UltimateOpenGL_Transform_h_
3 #include "Definition.h"
4 /*
5 	Transform Object from UltimateOpenGL
6 */
7 namespace Upp{
8 class Transform{
9 	public:
Transform()10 		Transform(){}
Transform(const Transform & _transform)11 		Transform(const Transform& _transform){*this = _transform;}
12 		Transform& operator=(const Transform& _transform){Front = _transform.Front; Up = _transform.Up; Right = _transform.Right; WorldUp = _transform.WorldUp; WorldFront = _transform.WorldFront; WorldRight = _transform.WorldRight; Position = _transform.Position; Rotation = _transform.Rotation; Scale = _transform.Scale; return *this;}
~Transform()13 		virtual ~Transform(){}
14 
SetFront(const glm::vec3 & vec3)15 		Transform& SetFront(const glm::vec3& vec3)noexcept{Front = vec3; return *this;}
SetUp(const glm::vec3 & vec3)16 		Transform& SetUp(const glm::vec3& vec3)noexcept{Up = vec3; return *this;}
SetRight(const glm::vec3 & vec3)17 		Transform& SetRight(const glm::vec3& vec3)noexcept{Right = vec3; return *this;}
SetWorldUp(const glm::vec3 & vec3)18 		Transform& SetWorldUp(const glm::vec3& vec3)noexcept{WorldUp = vec3; return *this;}
SetWorldFront(const glm::vec3 & vec3)19 		Transform& SetWorldFront(const glm::vec3& vec3)noexcept{WorldFront = vec3; return *this;}
SetWorldRight(const glm::vec3 & vec3)20 		Transform& SetWorldRight(const glm::vec3& vec3)noexcept{WorldRight = vec3; return *this;}
SetScale(const glm::vec3 & vec3)21 		Transform& SetScale(const glm::vec3& vec3)noexcept{Scale = vec3; return *this;}
SetPosition(const glm::vec3 & vec3)22 		Transform& SetPosition(const glm::vec3& vec3)noexcept{Position = vec3; return *this;}
SetPosition(float x,float y,float z)23 		Transform& SetPosition(float x, float y, float z)noexcept{Position.x =x; Position.y = y; Position.z = z; return *this;}
SetRotation(const glm::quat & quat)24 		Transform& SetRotation(const glm::quat& quat)noexcept{Rotation = quat; RecalculateFURW(); return *this;}
SetRotation(float Yaw,float Pitch,float Roll)25 		Transform& SetRotation(float Yaw, float Pitch, float Roll)noexcept{	Rotation = glm::quat(glm::vec3(Pitch, Yaw , Roll)); RecalculateFURW(); return *this;}
SetRotation(float angleDegree,const glm::vec3 & axis)26 		Transform& SetRotation(float angleDegree, const glm::vec3& axis)noexcept{float radHalfAngle =(float) glm::radians(angleDegree) / 2.0f; float sinVal = glm::sin(radHalfAngle); float cosVal = glm::cos(radHalfAngle); float xVal = axis.x * sinVal; float yVal = axis.y * sinVal; float zVal = axis.z * sinVal; Rotation = glm::quat(cosVal,xVal, yVal, zVal); RecalculateFURW(); return *this;}
27 
GetFront()28 		glm::vec3 GetFront()const noexcept{return Front;}
GetUp()29 		glm::vec3 GetUp()const noexcept{return Up;}
GetRight()30 		glm::vec3 GetRight()const noexcept{return Right;}
GetWorldUp()31 		glm::vec3 GetWorldUp()const noexcept{return WorldUp;}
GetWorldFront()32 		glm::vec3 GetWorldFront()const noexcept{return WorldFront;}
GetWorldRight()33 		glm::vec3 GetWorldRight()const noexcept{return WorldRight;}
GetPosition()34 		glm::vec3 GetPosition()const noexcept{return Position;}
GetRotation()35 		glm::quat GetRotation()const noexcept{return Rotation;}
GetScale()36 		glm::vec3 GetScale()const noexcept{return Scale;}
37 
Move(const glm::vec3 & vec3)38 		Transform& Move(const glm::vec3& vec3)noexcept{Position += vec3; return *this;}
Move(float x,float y,float z)39 		Transform& Move(float x, float y, float z)noexcept{Position += glm::vec3(x,y,z); return *this;}
40 
Rotate(const glm::quat & quat)41 		Transform& Rotate(const glm::quat& quat)noexcept{Rotation *= quat; RecalculateFURW(); return *this;}
Rotate(float Yaw,float Pitch,float Roll)42 		Transform& Rotate(float Yaw, float Pitch, float Roll)noexcept{Rotation *= glm::quat(glm::vec3(Pitch, Yaw , Roll)); RecalculateFURW(); return *this;}
Rotate(float angleDegree,const glm::vec3 & axis)43 		Transform& Rotate(float angleDegree, const glm::vec3& axis){float radHalfAngle =(float) glm::radians(angleDegree) / 2.0f; float sinVal = glm::sin(radHalfAngle); float cosVal = glm::cos(radHalfAngle);	float xVal = axis.x * sinVal; float yVal = axis.y * sinVal; float zVal = axis.z * sinVal; Rotation *= glm::quat(cosVal,xVal, yVal, zVal); RecalculateFURW(); return *this;}
44 
45 		Transform& LookAt(const glm::vec3& LookAt, glm::vec3 customUp = glm::vec3(0.0f,0.0f,0.0f))noexcept{
46 			glm::vec3 direction = LookAt - Position;
47 			float directionLength = glm::length(direction);
48 			if(directionLength > 0.0001){
49 				direction /= directionLength;
50 				if(customUp != glm::vec3(0.0f,0.0f,0.0f))
51 					SetRotation(glm::inverse(glm::quatLookAt(glm::normalize(direction), customUp)));
52 				else
53 					SetRotation(glm::inverse(glm::quatLookAt(glm::normalize(direction), Up)));
54 			}
55 			return *this;
56 		}
57 
GetViewMatrix()58 		glm::mat4 GetViewMatrix()const noexcept{return glm::lookAt(Position,Position + Front, Up);}
GetModelMatrix()59 		glm::mat4 GetModelMatrix()const noexcept{
60 			glm::mat4 ModelMatrix = glm::mat4(1.0f);
61 			ModelMatrix = glm::translate(ModelMatrix, Position); //position of cube
62 		    ModelMatrix = glm::scale(ModelMatrix, Scale); //Scale (not used so glm::vec3(1.0f))
63 			ModelMatrix *= glm::mat4_cast(Rotation);
64 			return ModelMatrix;
65 		}
66 
67 		//Static functions
GetQuaterion(float Yaw,float Pitch,float Roll)68 		static glm::quat GetQuaterion(float Yaw, float Pitch, float Roll)noexcept{
69 			return glm::quat(glm::vec3(Pitch, Yaw , Roll));
70 		}
GetQuaterion(float angleDegree,const glm::vec3 & axis)71 		static glm::quat GetQuaterion(float angleDegree, const glm::vec3& axis)noexcept{
72 			float radHalfAngle =(float) glm::radians(angleDegree) / 2.0f;
73 			float sinVal = glm::sin(radHalfAngle);
74 			float cosVal = glm::cos(radHalfAngle);
75 			float xVal = axis.x * sinVal;
76 			float yVal = axis.y * sinVal;
77 			float zVal = axis.z * sinVal;
78 			return glm::quat(cosVal,xVal, yVal, zVal);
79 		}
80 
GetEulerAngle(const glm::quat & quaterion)81 		static glm::vec3 GetEulerAngle(const glm::quat& quaterion){
82 			return glm::eulerAngles(quaterion);
83 		}
84 
TransformVectorByMatrix(const glm::vec3 & vector,const glm::mat4 & matrix)85 		static glm::vec3 TransformVectorByMatrix(const glm::vec3& vector,const glm::mat4& matrix){
86 			float w = vector[0]* matrix[0][3] + vector[1] * matrix[1][3] + vector[2] * matrix[2][3] + matrix[3][3];
87 			glm::vec3 ret;
88 			ret.x = (vector[0]*matrix[0][0]+vector[1]*matrix[1][0]+vector[2]*matrix[2][0]+matrix[3][0])/w;
89 			ret.y = (vector[0]*matrix[0][1]+vector[1]*matrix[1][1]+vector[2]*matrix[2][1]+matrix[3][1])/w;
90 			ret.z = (vector[0]*matrix[0][2]+vector[1]*matrix[1][2]+vector[2]*matrix[2][2]+matrix[3][2])/w;
91 			return ret;
92 		}
93 	private:
94 		glm::vec3 Front = glm::vec3(0.0f, 0.0f, -1.0f);
95 		glm::vec3 Up = glm::vec3(0.0f, 1.0f, 0.0f);
96 		glm::vec3 Right = glm::vec3(1.0f, 0.0f, 0.0f);
97 
98 		glm::vec3 WorldFront = glm::vec3(0.0, 0.0, -1.0);
99 		glm::vec3 WorldUp = glm::vec3(0.0f, 1.0f, 0.0f);
100 		glm::vec3 WorldRight = glm::vec3(1.0f, 0.0f, 0.0f);
101 
102 		glm::vec3 Position = glm::vec3(0.0f);
103 		glm::quat Rotation = Transform::GetQuaterion(0.0f,glm::vec3(0.0f,0.0f,0.0f));
104 		glm::vec3 Scale = glm::vec3(1.0f);
105 
RecalculateFURW()106 		void RecalculateFURW(){
107 			Front = glm::rotate(glm::inverse(Rotation), WorldFront);
108 		    Right = glm::rotate(glm::inverse(Rotation), WorldRight);
109 		    Up = glm::rotate(glm::inverse(Rotation), WorldUp);
110 		}
111 };
112 }
113 #endif
114