diff --git a/src/Viewer.cpp b/src/Viewer.cpp
index cfbedfd22359c316a029162f9ad3ea2ba827d964..4c0ea85584d23a4ab6f0f0b08d666499172f4e98 100644
--- a/src/Viewer.cpp
+++ b/src/Viewer.cpp
@@ -452,3 +452,22 @@ void Viewer::mainMenu()
 		ImGui::EndMenu();
 	}
 }
+
+namespace minity
+{
+	void matrixDecompose(const glm::mat4& matrix, glm::vec3& translation, glm::mat4& rotation, glm::vec3& scale)
+	{
+		translation = glm::vec3{matrix[3]};
+		glm::mat3 inner = glm::mat3{matrix};
+		
+		scale.x = glm::length(inner[0]);
+		scale.y = glm::length(inner[1]);
+		scale.z = glm::length(inner[2]);
+		
+		inner[0] /= scale.x;
+		inner[1] /= scale.y;
+		inner[2] /= scale.z;
+
+		rotation = glm::mat4{inner};
+	}
+}
diff --git a/src/Viewer.h b/src/Viewer.h
index 3217d1dbd51864a1f6c8abb2255f53beb4c06141..554cf539568af577fc337f9f7318e83df8f45812 100644
--- a/src/Viewer.h
+++ b/src/Viewer.h
@@ -14,7 +14,6 @@
 
 namespace minity
 {
-
 	class Viewer
 	{
 	public:
@@ -78,5 +77,14 @@ namespace minity
 		bool m_saveScreenshot = false;
 	};
 
-
+	/**
+	 * @brief Performs standard decomposition of a transformation matrix into translation, rotation and scale parts respectively.
+	 * Note: The out rotation is an affine space rotation matrix, meaning only the inner 3x3 part affects rotation and the rest is the identity matrix.
+	 * @see https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati
+	 * @param matrix The matrix to decompose
+	 * @param translation Out parameter for translation
+	 * @param rotation Out parameter for rotation
+	 * @param scale Out parameter for scale
+	 */
+	void matrixDecompose(const glm::mat4& matrix, glm::vec3& translation, glm::mat4& rotation, glm::vec3& scale);
 }
\ No newline at end of file