diff --git a/.gitmodules b/.gitmodules
index 3f17965d74c54abaabfb616bcad6481fc4500a6a..f3748ee10aa95ba9ef5f1c69d6bb67523667ef49 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,16 +1,16 @@
 [submodule "DMath"]
 	path = external/DMath
 	url = https://github.com/Didgy74/DMath.git
-	branch = master
+	branch = origin/master
 [submodule "fx-gltf"]
 	path = external/fx-gltf
 	url = https://github.com/jessey-git/fx-gltf.git
-	branch = master
+	branch = origin/master
 [submodule "nlohmann-json"]
 	path = external/nlohmann-json
 	url = https://github.com/nlohmann/json.git
-	branch = master
+	branch = origin/master
 [submodule "ktxlib"]
 	path = external/ktxlib
 	url = https://github.com/KhronosGroup/KTX-Software.git
-	branch = master
+	branch = origin/master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ac2c4c1c1ea46556a610f4df5c6617ee7cb4243..0e8ca488ae8e087ca3f7f5e9685323bfed65a61f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ if(WIN32)
 	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build")
 endif()
 
-file(GLOB_RECURSE SOURCE_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp")
+file(GLOB_RECURSE SOURCE_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp" "${CMAKE_SOURCE_DIR}/src/*.hpp" "${CMAKE_SOURCE_DIR}/src/*.inl")
 add_executable(${PROJECT_NAME} ${SOURCE_FILES})
 target_include_directories(${PROJECT_NAME} PRIVATE include)
 
diff --git a/external/DMath b/external/DMath
index 62afefe2fcf6db2471846d3b42800a0ae44f0f8e..a86909a7b37084c09c867efefa59faec47686128 160000
--- a/external/DMath
+++ b/external/DMath
@@ -1 +1 @@
-Subproject commit 62afefe2fcf6db2471846d3b42800a0ae44f0f8e
+Subproject commit a86909a7b37084c09c867efefa59faec47686128
diff --git a/src/Engine/Asset.cpp b/src/Engine/Asset.cpp
deleted file mode 100644
index 60331fb11e3676c751d4906b4f276bf4f4c3e527..0000000000000000000000000000000000000000
--- a/src/Engine/Asset.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-#define ASSET_TEXTURE_COUNT
-#define ASSET_MESH_COUNT
-#include "Asset.hpp"
-
-#include <cassert>
-#include <map>
-#include <type_traits>
-#include <iostream>
-
-#include "fx/gltf.h"
-
-struct AssetInfo
-{
-	std::string_view name;
-	std::string_view relativePath;
-};
-
-static const std::map<Asset::Sprite, AssetInfo> textureInfos
-{
-	{ Asset::Sprite::None, {"None" , ""} },
-	{ Asset::Sprite::Default, {"Default", "defaultTexture.png"} },
-	{ Asset::Sprite::Test, {"Test", "test.png"} },
-	{ Asset::Sprite::Circle, {"Circle", "circle.png"} },
-};
-
-static const std::map<size_t, AssetInfo> meshInfos
-{
-	{ size_t(Asset::Mesh::None), {"None", ""} },
-	{ size_t(Asset::Mesh::Cube), {"Cube", "Cube/Cube.gltf"} },
-	{ size_t(Asset::Mesh::SpritePlane), {"SpritePlane", "SpritePlane/SpritePlane.gltf"} },
-	{ size_t(Asset::Mesh::Helmet), {"Helmet", "Helmet/Helmet.gltf"} },
-};
-
-bool Asset::CheckValid(Sprite sprite)
-{
-	using Type = std::underlying_type_t<Sprite>;
-	return (0 <= static_cast<Type>(sprite) && static_cast<Type>(sprite) < static_cast<Type>(Sprite::COUNT)) || sprite == Sprite::None;
-}
-
-std::string Asset::GetMeshPath(size_t i)
-{
-	auto iterator = meshInfos.find(i);
-	if (iterator == meshInfos.end())
-		return {};
-	else
-		return std::string(meshFolderPath) + std::string(iterator->second.relativePath);
-}
-
-std::optional<Asset::MeshDocument> Asset::LoadMeshDocument(std::string_view path)
-{
-	try
-	{
-		const auto gltfDocument = fx::gltf::LoadFromText(std::string(path));
-
-		auto& primitive = gltfDocument.meshes[0].primitives[0];
-
-		auto posAccIterator = primitive.attributes.find("POSITION");
-		if (posAccIterator == primitive.attributes.end())
-		{
-			std::cerr << "Error. Found no position attribute for mesh." << std::endl;
-			return {};
-		}
-		auto& posAcc = gltfDocument.accessors[posAccIterator->second];
-		bool validAccessor = posAcc.type == fx::gltf::Accessor::Type::Vec3 && posAcc.componentType == fx::gltf::Accessor::ComponentType::Float;
-		if (!validAccessor)
-		{
-			std::cerr << "Error. Position attribute of mesh is in wrong format." << std::endl;
-			return {};
-		}
-		auto& posBufferView = gltfDocument.bufferViews[posAcc.bufferView];
-		const auto posByteOffset = posAcc.byteOffset + posBufferView.byteOffset;
-		
-
-		auto& uvAccessor = gltfDocument.accessors[primitive.attributes.find("TEXCOORD_0")->second];
-		assert(uvAccessor.type == fx::gltf::Accessor::Type::Vec2 && uvAccessor.componentType == fx::gltf::Accessor::ComponentType::Float);
-		auto& uvBufferView = gltfDocument.bufferViews[uvAccessor.bufferView];
-
-		
-
-		auto& normalAccessor = gltfDocument.accessors[primitive.attributes.find("NORMAL")->second];
-		assert(normalAccessor.type == fx::gltf::Accessor::Type::Vec3 && normalAccessor.componentType == fx::gltf::Accessor::ComponentType::Float);
-		auto& normalBufferView = gltfDocument.bufferViews[normalAccessor.bufferView];
-		
-
-		assert(posAcc.count == uvAccessor.count && posAcc.count == normalAccessor.count);
-
-		auto& indexAccessor = gltfDocument.accessors[primitive.indices];
-		assert(indexAccessor.type == fx::gltf::Accessor::Type::Scalar);
-		assert(indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort
-			|| indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedInt);
-		auto& indexBufferView = gltfDocument.bufferViews[indexAccessor.bufferView];
-
-		
-		MeshDocument::CreateInfo createInfo{};
-		createInfo.byteArray = std::move(gltfDocument.buffers[posBufferView.buffer].data);
-		createInfo.vertexCount = posAcc.count;
-		createInfo.posByteOffset = posByteOffset;
-		createInfo.uvByteOffset = uvBufferView.byteOffset + uvAccessor.byteOffset;
-		createInfo.normalByteOffset = normalBufferView.byteOffset + normalAccessor.byteOffset;
-		createInfo.indexByteOffset = indexBufferView.byteOffset + indexAccessor.byteOffset;
-		createInfo.indexCount = indexAccessor.count;
-		createInfo.indexType = indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort ? MeshDocument::IndexType::UInt16 : MeshDocument::IndexType::UInt32;
-
-		return { MeshDocument(std::move(createInfo)) };
-	}
-	catch (std::exception e)
-	{
-		std::cerr << "Asset System Error: Could not load file. Message: " << e.what() << std::endl;
-		return {};
-	}
-}
-
-Asset::TextureDocument Asset::LoadTextureDocument(Sprite texture)
-{
-	TextureDocument::CreateInfo createInfo{};
-
-	return TextureDocument(std::move(createInfo));
-}
-
-std::optional<Engine::Renderer::MeshDocument> Asset::LoadMesh(size_t i)
-{
-	auto path = GetMeshPath(i);
-	if (path == "")
-		return {};
-
-	auto assetMeshDocOpt = LoadMeshDocument(path);
-	if (assetMeshDocOpt.has_value() == false)
-		return {};
-
-	auto oldInfo = MeshDocument::ToCreateInfo(std::move(assetMeshDocOpt.value()));
-
-	using namespace Engine;
-	Renderer::MeshDocument::CreateInfo newInfo;
-	newInfo.byteArray = std::move(oldInfo.byteArray);
-	newInfo.vertexCount = std::move(oldInfo.vertexCount);
-	newInfo.indexCount = std::move(oldInfo.indexCount);
-	newInfo.indexType = oldInfo.indexType == MeshDocument::IndexType::UInt16 ? Renderer::MeshDocument::IndexType::UInt16 : Renderer::MeshDocument::IndexType::UInt32;
-
-	newInfo.posByteOffset = std::move(oldInfo.posByteOffset);
-	newInfo.uvByteOffset = std::move(oldInfo.uvByteOffset);
-	newInfo.normalByteOffset = std::move(oldInfo.normalByteOffset);
-	newInfo.tangentByteOffset = std::move(oldInfo.tangentByteOffset);
-	newInfo.indexByteOffset = std::move(oldInfo.indexByteOffset);
-
-	return Renderer::MeshDocument(std::move(newInfo));
-}
-
-static Asset::MeshDocument::IndexType ToIndexType(fx::gltf::Accessor::ComponentType componentType)
-{
-	switch (componentType)
-	{
-	case fx::gltf::Accessor::ComponentType::UnsignedShort:
-		return Asset::MeshDocument::IndexType::UInt16;
-	case fx::gltf::Accessor::ComponentType::UnsignedInt:
-		return Asset::MeshDocument::IndexType::UInt32;
-	default:
-		return static_cast<Asset::MeshDocument::IndexType>(-1);
-	}
-}
-
-Asset::MeshDocument::CreateInfo Asset::MeshDocument::ToCreateInfo(MeshDocument&& input)
-{
-	CreateInfo returnValue;
-
-	returnValue.byteArray = std::move(input.byteArray);
-	returnValue.vertexCount = std::move(input.vertexCount);
-	returnValue.indexType = std::move(input.indexType);
-	returnValue.indexCount = std::move(input.indexCount);
-
-	returnValue.posByteOffset = std::move(input.GetByteOffset(Attribute::Position));
-	returnValue.uvByteOffset = std::move(input.GetByteOffset(Attribute::TexCoord));
-	returnValue.normalByteOffset = std::move(input.GetByteOffset(Attribute::Normal));
-	returnValue.tangentByteOffset = std::move(input.GetByteOffset(Attribute::Tangent));
-	returnValue.indexByteOffset = std::move(input.GetByteOffset(Attribute::Index));
-
-	return returnValue;
-}
-
-Asset::MeshDocument::MeshDocument(CreateInfo&& info) :
-	byteArray(std::move(info.byteArray)),
-	indexType(info.indexType),
-	vertexCount(info.vertexCount),
-	indexCount(info.indexCount)
-{
-	GetByteOffset(Attribute::Position) = info.posByteOffset;
-	GetByteOffset(Attribute::TexCoord) = info.uvByteOffset;
-	GetByteOffset(Attribute::Normal) = info.normalByteOffset;
-	GetByteOffset(Attribute::Tangent) = info.normalByteOffset;
-	GetByteOffset(Attribute::Index) = info.indexByteOffset;
-}
-
-const std::vector<uint8_t>& Asset::MeshDocument::GetByteArray() const { return byteArray; }
-
-Asset::MeshDocument::IndexType Asset::MeshDocument::GetIndexType() const { return indexType; }
-
-const uint8_t* Asset::MeshDocument::GetDataPtr(Attribute type) const
-{
-	return byteArray.data() + byteOffsets.at(size_t(type));
-}
-
-size_t& Asset::MeshDocument::GetByteOffset(Attribute type) { return byteOffsets.at(size_t(type)); }
-
-const size_t& Asset::MeshDocument::GetByteOffset(Attribute type) const { return byteOffsets.at(size_t(type)); }
-
-uint8_t Asset::MeshDocument::ToByteSize(IndexType indexType)
-{
-	return indexType == IndexType::UInt16 ? uint8_t(2) : uint8_t(4);
-}
-
-Asset::TextureDocument::TextureDocument(CreateInfo&& right) :
-	byteArray(right.byteArray),
-	dimensions(right.dimensions),
-	channelCount(right.channelCount),
-	owner(true)
-{
-}
-
-Asset::TextureDocument::TextureDocument(TextureDocument&& right) :
-	byteArray(right.byteArray),
-	dimensions(right.dimensions),
-	channelCount(right.channelCount),
-	owner(true)
-{
-	right.owner = false;
-}
-
-Asset::TextureDocument::~TextureDocument()
-{
-	if (owner)
-		delete[] byteArray;
-}
-
-Utility::ImgDim Asset::TextureDocument::GetDimensions() const { return dimensions; }
-
-const uint8_t* Asset::TextureDocument::GetData() const { return byteArray; }
-
-uint8_t Asset::TextureDocument::GetChannelCount() const { return channelCount; }
-
-size_t Asset::TextureDocument::GetByteLength() const
-{
-	return dimensions.width * dimensions.height * channelCount;
-}
diff --git a/src/Engine/Asset.hpp b/src/Engine/Asset.hpp
deleted file mode 100644
index 841eb6b34b133ff7314dcce7d94c0b1097d46fa4..0000000000000000000000000000000000000000
--- a/src/Engine/Asset.hpp
+++ /dev/null
@@ -1,150 +0,0 @@
-#pragma once
-
-#include "Utility/ImgDim.hpp"
-
-#include <string>
-#include <string_view>
-#include <cstdint>
-#include <vector>
-#include <array>
-#include <optional>
-
-#include "Renderer/MeshDocument.hpp"
-
-namespace Asset
-{
-	constexpr std::string_view textureFolderPath = "Data/Textures/";
-	constexpr std::string_view meshFolderPath = "Data/Meshes/";
-
-	class MeshDocument;
-	class TextureDocument;
-
-	enum class Sprite : uint32_t;
-	bool CheckValid(Sprite texture);
-
-	enum class Mesh : uint32_t;
-	std::string GetMeshPath(size_t i);
-
-	MeshDocument LoadMeshDocument(Mesh mesh);
-	std::optional<MeshDocument> LoadMeshDocument(std::string_view path);
-	TextureDocument LoadTextureDocument(Sprite texture);
-
-	std::optional<Engine::Renderer::MeshDocument> LoadMesh(size_t i);
-}
-
-class Asset::MeshDocument
-{
-public:
-	using PositionType = std::array<float, 3>;
-	using UVType = std::array<float, 2>;
-	using NormalType = std::array<float, 3>;
-	using TangentType = std::array<float, 3>;
-
-	enum class IndexType
-	{
-		UInt16,
-		UInt32
-	};
-
-	enum class Attribute
-	{
-		Position,
-		TexCoord,
-		Normal,
-		Tangent,
-		Index,
-		COUNT
-	};
-
-	struct CreateInfo
-	{
-		std::vector<uint8_t> byteArray;
-		size_t posByteOffset;
-		size_t uvByteOffset;
-		size_t normalByteOffset;
-		size_t tangentByteOffset;
-		size_t indexByteOffset;
-		IndexType indexType;
-		uint32_t vertexCount;
-		uint32_t indexCount;
-	};
-
-	MeshDocument(CreateInfo&& info);
-	MeshDocument(MeshDocument&&) = default;
-	MeshDocument(const MeshDocument&) = default;
-
-	const std::vector<uint8_t>& GetByteArray() const;
-	const size_t& GetByteOffset(Attribute attr) const;
-	size_t GetByteLength(Attribute attr) const;
-	const uint8_t* GetDataPtr(Attribute attr) const;
-
-	uint32_t GetVertexCount() const;
-
-	IndexType GetIndexType() const;
-	uint32_t GetIndexCount() const;
-
-	size_t GetTotalSizeRequired() const;
-
-	static uint8_t ToByteSize(IndexType indexType);
-	static CreateInfo ToCreateInfo(MeshDocument&& input);
-
-private:
-	size_t& GetByteOffset(Attribute attr);
-
-	std::vector<uint8_t> byteArray;
-	std::array<size_t, static_cast<size_t>(Attribute::COUNT)> byteOffsets;
-	uint32_t vertexCount;
-	IndexType indexType;
-	uint32_t indexCount;
-};
-
-class Asset::TextureDocument
-{
-public:
-	struct CreateInfo
-	{
-		Utility::ImgDim dimensions;
-		uint8_t* byteArray;
-		uint8_t channelCount;
-	};
-
-	TextureDocument(CreateInfo&&);
-	TextureDocument(TextureDocument&&);
-	TextureDocument(const TextureDocument&) = delete;
-	~TextureDocument();
-
-	Utility::ImgDim GetDimensions() const;
-	const uint8_t* GetData() const;
-	uint8_t GetChannelCount() const;
-
-	size_t GetByteLength() const;
-
-private:
-	Utility::ImgDim dimensions;
-	bool owner;
-	uint8_t* byteArray;
-	uint8_t channelCount;
-};
-
-enum class Asset::Sprite : uint32_t
-{
-	None,
-	Default,
-	Test, 
-	Circle,
-#ifdef ASSET_TEXTURE_COUNT
-	COUNT
-#endif
-};
-
-enum class Asset::Mesh : uint32_t
-{
-	None,
-	Plane,
-	Cube,
-	SpritePlane,
-	Helmet,
-#ifdef ASSET_MESH_COUNT
-	COUNT
-#endif
-};
\ No newline at end of file
diff --git a/src/Engine/AssetManager/AssetManager.cpp b/src/Engine/AssetManager/AssetManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74a96f37b467135f281e6b62167663fa1d37dc0d
--- /dev/null
+++ b/src/Engine/AssetManager/AssetManager.cpp
@@ -0,0 +1,77 @@
+#include "AssetManager.hpp"
+#include "MeshDocument.hpp"
+#include "TextureDocument.hpp"
+
+#include <cassert>
+#include <map>
+#include <type_traits>
+#include <iostream>
+#include <string_view>
+
+struct AssetManagerInfo
+{
+	std::string_view name;
+	std::string_view relativePath;
+};
+
+static const std::map<Engine::AssetManager::Sprite, AssetManagerInfo> textureInfos
+{
+	{ Engine::AssetManager::Sprite::None, {"None" , ""} },
+	{ Engine::AssetManager::Sprite::Default, {"Default", "defaultTexture.png"} },
+	{ Engine::AssetManager::Sprite::Test, {"Test", "test.png"} },
+	{ Engine::AssetManager::Sprite::Circle, {"Circle", "circle.png"} },
+};
+
+static const std::map<size_t, AssetManagerInfo> meshInfos
+{
+	{ size_t(Engine::AssetManager::Mesh::None), {"None", ""} },
+	{ size_t(Engine::AssetManager::Mesh::Cube), {"Cube", "Cube/Cube.gltf"} },
+	{ size_t(Engine::AssetManager::Mesh::SpritePlane), {"SpritePlane", "SpritePlane/SpritePlane.gltf"} },
+	{ size_t(Engine::AssetManager::Mesh::Helmet), {"Helmet", "Helmet/Helmet.gltf"} },
+};
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		std::string GetMeshPath(size_t i)
+		{
+			auto iterator = meshInfos.find(i);
+			if (iterator == meshInfos.end())
+				return {};
+			else
+				return std::string(meshFolderPath) + std::string(iterator->second.relativePath);
+		}
+
+		std::optional<Renderer::MeshDocument> AssetManager::LoadMesh(size_t i)
+		{
+			auto path = GetMeshPath(i);
+			if (path == "")
+				return {};
+
+			auto AssetManagerMeshDocOpt = LoadMeshDocument(path);
+			if (AssetManagerMeshDocOpt.has_value() == false)
+				return {};
+
+			auto oldInfo = MeshDocument::ToCreateInfo(std::move(AssetManagerMeshDocOpt.value()));
+
+			Renderer::MeshDocument::CreateInfo newInfo;
+			newInfo.byteArray = std::move(oldInfo.byteArray);
+			newInfo.vertexCount = std::move(oldInfo.vertexCount);
+			newInfo.indexCount = std::move(oldInfo.indexCount);
+			newInfo.indexType = oldInfo.indexType == MeshDocument::IndexType::UInt16 ? Renderer::MeshDocument::IndexType::UInt16 : Renderer::MeshDocument::IndexType::UInt32;
+
+			newInfo.posByteOffset = std::move(oldInfo.posByteOffset);
+			newInfo.uvByteOffset = std::move(oldInfo.uvByteOffset);
+			newInfo.normalByteOffset = std::move(oldInfo.normalByteOffset);
+			newInfo.tangentByteOffset = std::move(oldInfo.tangentByteOffset);
+			newInfo.indexByteOffset = std::move(oldInfo.indexByteOffset);
+
+			return { Renderer::MeshDocument(std::move(newInfo)) };
+		}
+	}
+	
+}
+
+#include "MeshDocument.inl"
+#include "TextureDocument.inl"
\ No newline at end of file
diff --git a/src/Engine/AssetManager/AssetManager.hpp b/src/Engine/AssetManager/AssetManager.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed4ba0370cc04ec834a8ad6c41086fa1f59c73b4
--- /dev/null
+++ b/src/Engine/AssetManager/AssetManager.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Typedefs.hpp"
+#include "MeshDocument.hpp"
+#include "TextureDocument.hpp"
+
+#include <string>
+#include <string_view>
+#include <optional>
+
+#include "../Renderer/MeshDocument.hpp"
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		constexpr std::string_view textureFolderPath = "Data/Textures/";
+		constexpr std::string_view meshFolderPath = "Data/Meshes/";
+
+		std::string GetMeshPath(size_t i);
+
+		std::optional<Renderer::MeshDocument> LoadMesh(size_t i);
+	}
+
+	namespace AssMan = AssetManager;
+}
\ No newline at end of file
diff --git a/src/Engine/AssetManager/MeshDocument.hpp b/src/Engine/AssetManager/MeshDocument.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f1950fe64bfbb1b1b15669fab0db40b30f8e0a97
--- /dev/null
+++ b/src/Engine/AssetManager/MeshDocument.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <vector>
+#include <array>
+#include <string_view>
+#include <optional>
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		class MeshDocument
+		{
+		public:
+			using PositionType = std::array<float, 3>;
+			using UVType = std::array<float, 2>;
+			using NormalType = std::array<float, 3>;
+			using TangentType = std::array<float, 3>;
+
+			enum class IndexType
+			{
+				UInt16,
+				UInt32
+			};
+
+			enum class Attribute
+			{
+				Position,
+				TexCoord,
+				Normal,
+				Tangent,
+				Index,
+				COUNT
+			};
+
+			struct CreateInfo
+			{
+				std::vector<uint8_t> byteArray;
+				size_t posByteOffset;
+				size_t uvByteOffset;
+				size_t normalByteOffset;
+				size_t tangentByteOffset;
+				size_t indexByteOffset;
+				IndexType indexType;
+				uint32_t vertexCount;
+				uint32_t indexCount;
+			};
+
+			MeshDocument(CreateInfo&& info);
+			MeshDocument(MeshDocument&&) = default;
+			MeshDocument(const MeshDocument&) = default;
+
+			const std::vector<uint8_t>& GetByteArray() const;
+			const size_t& GetByteOffset(Attribute attr) const;
+			size_t GetByteLength(Attribute attr) const;
+			const uint8_t* GetDataPtr(Attribute attr) const;
+
+			uint32_t GetVertexCount() const;
+
+			IndexType GetIndexType() const;
+			uint32_t GetIndexCount() const;
+
+			size_t GetTotalSizeRequired() const;
+
+			static uint8_t ToByteSize(IndexType indexType);
+			static CreateInfo ToCreateInfo(MeshDocument&& input);
+
+		private:
+			size_t& GetByteOffset(Attribute attr);
+
+			std::vector<uint8_t> byteArray;
+			std::array<size_t, static_cast<size_t>(Attribute::COUNT)> byteOffsets;
+			uint32_t vertexCount;
+			IndexType indexType;
+			uint32_t indexCount;
+		};
+
+		std::optional<MeshDocument> LoadMeshDocument(std::string_view path);
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/AssetManager/MeshDocument.inl b/src/Engine/AssetManager/MeshDocument.inl
new file mode 100644
index 0000000000000000000000000000000000000000..1fca96722885270217e9a0dfba44d11fe428afe8
--- /dev/null
+++ b/src/Engine/AssetManager/MeshDocument.inl
@@ -0,0 +1,137 @@
+#pragma once
+#include "MeshDocument.hpp"
+
+#include "fx/gltf.h"
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		static MeshDocument::IndexType ToIndexType(fx::gltf::Accessor::ComponentType componentType)
+		{
+			switch (componentType)
+			{
+			case fx::gltf::Accessor::ComponentType::UnsignedShort:
+				return MeshDocument::IndexType::UInt16;
+			case fx::gltf::Accessor::ComponentType::UnsignedInt:
+				return MeshDocument::IndexType::UInt32;
+			default:
+				assert(false);
+				return static_cast<MeshDocument::IndexType>(-1);
+			}
+		}
+
+		std::optional<MeshDocument> LoadMeshDocument(std::string_view path)
+		{
+			try
+			{
+				const auto gltfDocument = fx::gltf::LoadFromText(std::string(path));
+
+				auto& primitive = gltfDocument.meshes[0].primitives[0];
+
+				auto posAccIterator = primitive.attributes.find("POSITION");
+				if (posAccIterator == primitive.attributes.end())
+				{
+					std::cerr << "Error. Found no position attribute for mesh." << std::endl;
+					return {};
+				}
+				auto& posAcc = gltfDocument.accessors[posAccIterator->second];
+				bool validAccessor = posAcc.type == fx::gltf::Accessor::Type::Vec3 && posAcc.componentType == fx::gltf::Accessor::ComponentType::Float;
+				if (!validAccessor)
+				{
+					std::cerr << "Error. Position attribute of mesh is in wrong format." << std::endl;
+					return {};
+				}
+				auto& posBufferView = gltfDocument.bufferViews[posAcc.bufferView];
+				const auto posByteOffset = posAcc.byteOffset + posBufferView.byteOffset;
+
+
+				auto& uvAccessor = gltfDocument.accessors[primitive.attributes.find("TEXCOORD_0")->second];
+				assert(uvAccessor.type == fx::gltf::Accessor::Type::Vec2 && uvAccessor.componentType == fx::gltf::Accessor::ComponentType::Float);
+				auto & uvBufferView = gltfDocument.bufferViews[uvAccessor.bufferView];
+
+
+
+				auto & normalAccessor = gltfDocument.accessors[primitive.attributes.find("NORMAL")->second];
+				assert(normalAccessor.type == fx::gltf::Accessor::Type::Vec3 && normalAccessor.componentType == fx::gltf::Accessor::ComponentType::Float);
+				auto & normalBufferView = gltfDocument.bufferViews[normalAccessor.bufferView];
+
+
+				assert(posAcc.count == uvAccessor.count && posAcc.count == normalAccessor.count);
+
+				auto & indexAccessor = gltfDocument.accessors[primitive.indices];
+				assert(indexAccessor.type == fx::gltf::Accessor::Type::Scalar);
+				assert(indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort
+					|| indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedInt);
+				auto & indexBufferView = gltfDocument.bufferViews[indexAccessor.bufferView];
+
+
+				MeshDocument::CreateInfo createInfo{};
+				createInfo.byteArray = std::move(gltfDocument.buffers[posBufferView.buffer].data);
+				createInfo.vertexCount = posAcc.count;
+				createInfo.posByteOffset = posByteOffset;
+				createInfo.uvByteOffset = uvBufferView.byteOffset + uvAccessor.byteOffset;
+				createInfo.normalByteOffset = normalBufferView.byteOffset + normalAccessor.byteOffset;
+				createInfo.indexByteOffset = indexBufferView.byteOffset + indexAccessor.byteOffset;
+				createInfo.indexCount = indexAccessor.count;
+				createInfo.indexType = ToIndexType(indexAccessor.componentType);
+
+				return { MeshDocument(std::move(createInfo)) };
+			}
+			catch (std::exception e)
+			{
+				std::cerr << "AssetManager System Error: Could not load file. Message: " << e.what() << std::endl;
+				return {};
+			}
+		}
+
+		MeshDocument::CreateInfo AssetManager::MeshDocument::ToCreateInfo(MeshDocument&& input)
+		{
+			CreateInfo returnValue;
+
+			returnValue.byteArray = std::move(input.byteArray);
+			returnValue.vertexCount = std::move(input.vertexCount);
+			returnValue.indexType = std::move(input.indexType);
+			returnValue.indexCount = std::move(input.indexCount);
+
+			returnValue.posByteOffset = std::move(input.GetByteOffset(Attribute::Position));
+			returnValue.uvByteOffset = std::move(input.GetByteOffset(Attribute::TexCoord));
+			returnValue.normalByteOffset = std::move(input.GetByteOffset(Attribute::Normal));
+			returnValue.tangentByteOffset = std::move(input.GetByteOffset(Attribute::Tangent));
+			returnValue.indexByteOffset = std::move(input.GetByteOffset(Attribute::Index));
+
+			return returnValue;
+		}
+
+		AssetManager::MeshDocument::MeshDocument(CreateInfo && info) :
+			byteArray(std::move(info.byteArray)),
+			indexType(info.indexType),
+			vertexCount(info.vertexCount),
+			indexCount(info.indexCount)
+		{
+			GetByteOffset(Attribute::Position) = info.posByteOffset;
+			GetByteOffset(Attribute::TexCoord) = info.uvByteOffset;
+			GetByteOffset(Attribute::Normal) = info.normalByteOffset;
+			GetByteOffset(Attribute::Tangent) = info.normalByteOffset;
+			GetByteOffset(Attribute::Index) = info.indexByteOffset;
+		}
+
+		const std::vector<uint8_t>& AssetManager::MeshDocument::GetByteArray() const { return byteArray; }
+
+		AssetManager::MeshDocument::IndexType AssetManager::MeshDocument::GetIndexType() const { return indexType; }
+
+		const uint8_t* AssetManager::MeshDocument::GetDataPtr(Attribute type) const
+		{
+			return byteArray.data() + byteOffsets.at(size_t(type));
+		}
+
+		size_t& AssetManager::MeshDocument::GetByteOffset(Attribute type) { return byteOffsets.at(size_t(type)); }
+
+		const size_t& AssetManager::MeshDocument::GetByteOffset(Attribute type) const { return byteOffsets.at(size_t(type)); }
+
+		uint8_t AssetManager::MeshDocument::ToByteSize(IndexType indexType)
+		{
+			return indexType == IndexType::UInt16 ? uint8_t(2) : uint8_t(4);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/AssetManager/TextureDocument.hpp b/src/Engine/AssetManager/TextureDocument.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..83403430fe7ed10f81a67dbd12573f0edb83ca49
--- /dev/null
+++ b/src/Engine/AssetManager/TextureDocument.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <array>
+#include <vector>
+#include <optional>
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		class TextureDocument
+		{
+		public:
+			enum class Format;
+
+		private:
+			Format format;
+			std::array<uint32_t, 2> dimensions;
+			std::vector<uint8_t> byteArray;
+		};
+
+		enum class TextureDocument::Format
+		{
+			RGBA
+		};
+
+		std::optional<TextureDocument> LoadTextureDocument(std::string path);
+	}
+
+	namespace AssMan = AssetManager;
+}
\ No newline at end of file
diff --git a/src/Engine/AssetManager/TextureDocument.inl b/src/Engine/AssetManager/TextureDocument.inl
new file mode 100644
index 0000000000000000000000000000000000000000..288748324561c24d5b99f2001a87cd17f0fdaf3f
--- /dev/null
+++ b/src/Engine/AssetManager/TextureDocument.inl
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "TextureDocument.hpp"
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		std::optional<TextureDocument> LoadTextureDocument(std::string path)
+		{
+			return {};
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/AssetManager/Typedefs.hpp b/src/Engine/AssetManager/Typedefs.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0e627fb85f1644802c93714bf3405898e984da27
--- /dev/null
+++ b/src/Engine/AssetManager/Typedefs.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <cstdint>
+
+namespace Engine
+{
+	namespace AssetManager
+	{
+		enum class Sprite : uint32_t;
+		enum class Mesh : uint32_t;
+
+		class MeshDocument;
+		class TextureDocument;
+	}
+
+	namespace AssMan = AssetManager;
+}
+
+enum class Engine::AssetManager::Sprite : uint32_t
+{
+	None,
+	Default,
+	Test,
+	Circle,
+#ifdef ASSETMANAGER_TEXTURE_COUNT
+	COUNT
+#endif
+};
+
+enum class Engine::AssetManager::Mesh : uint32_t
+{
+	None,
+	Plane,
+	Cube,
+	SpritePlane,
+	Helmet,
+#ifdef ASSETMANAGER_MESH_COUNT
+	COUNT
+#endif
+};
\ No newline at end of file
diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp
index 627ae6a1400197690bee259dca73e00ab49f52e6..30b6cbd23cfcb00dad11ea4a5bb96a78be573ec6 100644
--- a/src/Engine/Components/MeshRenderer.cpp
+++ b/src/Engine/Components/MeshRenderer.cpp
@@ -17,7 +17,7 @@ namespace Engine
 	{
 		MeshRenderer::MeshRenderer(SceneObject& owningSceneObject) :
 			ParentType(owningSceneObject),
-			mesh(Asset::Mesh::None),
+			mesh(AssMan::Mesh::None),
 			positionOffset{ 0, 0, 0 },
 			scale{ 1, 1, 1 },
 			rotation()
@@ -28,11 +28,11 @@ namespace Engine
 		{
 		}
 
-		Asset::Mesh MeshRenderer::GetMesh() const { return mesh; }
+		AssMan::Mesh MeshRenderer::GetMesh() const { return mesh; }
 
-		std::underlying_type_t<Asset::Mesh> MeshRenderer::GetMeshID() const { return static_cast<std::underlying_type_t<Asset::Mesh>>(GetMesh()); }
+		std::underlying_type_t<AssMan::Mesh> MeshRenderer::GetMeshID() const { return static_cast<std::underlying_type_t<AssMan::Mesh>>(GetMesh()); }
 
-		void MeshRenderer::SetMesh(Asset::Mesh newMesh)
+		void MeshRenderer::SetMesh(AssMan::Mesh newMesh)
 		{
 			if (GetMesh() == newMesh)
 				return;
diff --git a/src/Engine/Components/MeshRenderer.hpp b/src/Engine/Components/MeshRenderer.hpp
index 18841df923246c7e83b1db353504cce7f771d74b..c920a15c92051e92c4cf8b2648242f9d0b9cff56 100644
--- a/src/Engine/Components/MeshRenderer.hpp
+++ b/src/Engine/Components/MeshRenderer.hpp
@@ -2,7 +2,7 @@
 
 #include "Components.hpp"
 
-#include "../Asset.hpp"
+#include "../AssetManager/AssetManager.hpp"
 
 #include "../Enum.hpp"
 
@@ -22,9 +22,9 @@ namespace Engine
 			explicit MeshRenderer(SceneObject& owningObject);
 			~MeshRenderer();
 
-			[[nodiscard]] Asset::Mesh GetMesh() const;
-			std::underlying_type_t<Asset::Mesh> GetMeshID() const;
-			void SetMesh(Asset::Mesh newMesh);
+			[[nodiscard]] AssMan::Mesh GetMesh() const;
+			std::underlying_type_t<AssMan::Mesh> GetMeshID() const;
+			void SetMesh(AssMan::Mesh newMesh);
 
 			[[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const;
 			Math::Matrix4x4 GetModel(Space space) const;
@@ -34,7 +34,7 @@ namespace Engine
 			Math::Vector3D scale;
 
 		private:
-			Asset::Mesh mesh;
+			AssMan::Mesh mesh;
 		};
 	}
 }
diff --git a/src/Engine/Components/SpriteRenderer.cpp b/src/Engine/Components/SpriteRenderer.cpp
index f46ff15a45cecdebebee85b660f7ccf5277d4d24..e13eb3c6aa629a08b33cfb829c0cd3fc96f2193f 100644
--- a/src/Engine/Components/SpriteRenderer.cpp
+++ b/src/Engine/Components/SpriteRenderer.cpp
@@ -14,7 +14,7 @@ namespace Engine
 	{
 		SpriteRenderer::SpriteRenderer(SceneObject& owningObject) :
 			ParentType(owningObject),
-			sprite(Asset::Sprite::None),
+			sprite(AssMan::Sprite::None),
 			positionOffset{ 0, 0 },
 			rotation(0),
 			scale{ 1, 1 }
@@ -25,17 +25,15 @@ namespace Engine
 		{
 		}
 
-		void SpriteRenderer::SetSprite(Asset::Sprite newSprite)
+		void SpriteRenderer::SetSprite(AssMan::Sprite newSprite)
 		{
 			if (GetSprite() == newSprite)
 				return;
 
-			assert(Asset::CheckValid(newSprite));
-
 			sprite = newSprite;
 		}
 
-		Asset::Sprite SpriteRenderer::GetSprite() const { return sprite; }
+		AssMan::Sprite SpriteRenderer::GetSprite() const { return sprite; }
 
 		Math::Matrix<3, 2> SpriteRenderer::GetModel2D_Reduced(Space space) const
 		{
diff --git a/src/Engine/Components/SpriteRenderer.hpp b/src/Engine/Components/SpriteRenderer.hpp
index 70994367f7f2f6dfea79ec033718cb5bae774190..8018258280275ccb6d300aee176324ee7c260803 100644
--- a/src/Engine/Components/SpriteRenderer.hpp
+++ b/src/Engine/Components/SpriteRenderer.hpp
@@ -2,7 +2,7 @@
 
 #include "Components.hpp"
 
-#include "../Asset.hpp"
+#include "../AssetManager/AssetManager.hpp"
 
 #include "DMath/Vector/Vector.hpp"
 #include "DMath/Matrix/Matrix.hpp"
@@ -21,8 +21,8 @@ namespace Engine
 			explicit SpriteRenderer(SceneObject& owningObject);
 			~SpriteRenderer();
 
-			void SetSprite(Asset::Sprite newTexture);
-			[[nodiscard]] Asset::Sprite GetSprite() const;
+			void SetSprite(AssMan::Sprite newTexture);
+			[[nodiscard]] AssMan::Sprite GetSprite() const;
 
 			Math::Matrix<3, 2> GetModel2D_Reduced(Space space) const;
 			Math::Matrix4x4 GetModel(Space space) const;
@@ -32,7 +32,7 @@ namespace Engine
 			Math::Vector2D scale;
 
 		private:
-			Asset::Sprite sprite;
+			AssMan::Sprite sprite;
 		};
 	}
 	
diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp
index 3485afaa8eaade7e4de8b876a4e5d0c3d2485006..c312ea4f654ed51ea95a4aee53b79f51bdd2d086 100644
--- a/src/Engine/Engine.cpp
+++ b/src/Engine/Engine.cpp
@@ -17,8 +17,6 @@
 
 #include "Systems/RenderSystem.hpp"
 
-#include "DMath/LinearTransform3D.hpp"
-
 #include "Components/ScriptBase.hpp"
 
 #include <iostream>
@@ -70,7 +68,7 @@ namespace Engine
 		rendererInitInfo.surfaceDimensions = Application::GetWindowSize();
 		rendererInitInfo.surfaceHandle = Application::Core::GetMainWindowHandle();
 
-		rendererInitInfo.assetLoadCreateInfo.meshLoader = &Asset::LoadMesh;
+		rendererInitInfo.assetLoadCreateInfo.meshLoader = &AssMan::LoadMesh;
 
 		rendererInitInfo.openGLInitInfo.glSwapBuffers = &Application::Core::GL_SwapWindow;
 		Renderer::Core::Initialize(rendererInitInfo);
@@ -79,6 +77,7 @@ namespace Engine
 
 void Engine::Core::Run()
 {
+
 	Application::Core::Initialize(Application::API3D::OpenGL);
 	Time::Core::Initialize();
 	Input::Core::Initialize();
@@ -96,14 +95,14 @@ void Engine::Core::Run()
 
 	auto& sceneObject1 = scene1.NewSceneObject();
 	auto& mesh1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get();
-	mesh1.SetMesh(Asset::Mesh::Helmet);
+	mesh1.SetMesh(AssMan::Mesh::Helmet);
 
 	auto& meshTest = sceneObject1.AddComponent<Components::MeshRenderer>().first.get();
-	meshTest.SetMesh(Asset::Mesh::Helmet);
+	meshTest.SetMesh(AssMan::Mesh::Helmet);
 	meshTest.positionOffset.x = -3.f;
 
 	auto& mesh2 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get();
-	mesh2.SetMesh(Asset::Mesh::Cube);
+	mesh2.SetMesh(AssMan::Mesh::Cube);
 	mesh2.positionOffset.x = 2.f;
 
 	auto& objCamera = scene1.NewSceneObject();
@@ -115,14 +114,14 @@ void Engine::Core::Run()
 	Components::PointLight& light1 = lightObj.AddComponent<Components::PointLight>().first.get();
 	light1.color = { 1.f, 0.5f, 0.f };
 	auto& mesh3 = lightObj.AddComponent<Components::MeshRenderer>().first.get();
-	mesh3.SetMesh(Asset::Mesh::Cube);
+	mesh3.SetMesh(AssMan::Mesh::Cube);
 	mesh3.scale = { 0.1f, 0.1f, 0.1f };
 
 	auto& obj4 = scene1.NewSceneObject();
 	obj4.transform.localPosition = { 0.f, -7.5f, -10.f };
 	Components::PointLight& light3 = obj4.AddComponent<Components::PointLight>().first.get();
 	auto& mesh4 = obj4.AddComponent<Components::MeshRenderer>().first.get();
-	mesh4.SetMesh(Asset::Mesh::Cube);
+	mesh4.SetMesh(AssMan::Mesh::Cube);
 	mesh4.scale = { 0.1f, 0.1f, 0.1f };
 
 
diff --git a/src/Engine/Renderer/MeshDocument.hpp b/src/Engine/Renderer/MeshDocument.hpp
index dc46a1db5d283748d63f4ee965f790613aaf9488..695ba4a3328bc8433dc3ad5408a9def015f21e09 100644
--- a/src/Engine/Renderer/MeshDocument.hpp
+++ b/src/Engine/Renderer/MeshDocument.hpp
@@ -3,6 +3,8 @@
 #include <cstddef>
 #include <array>
 
+#include <cassert>
+
 namespace Engine
 {
 	namespace Renderer
diff --git a/src/Engine/Renderer/Renderer.hpp b/src/Engine/Renderer/Renderer.hpp
index 9ccf32c6551c1038e291f9533b3725e848ad492b..2abf2052789b8a7844215cfee93d7c50ab2dab41 100644
--- a/src/Engine/Renderer/Renderer.hpp
+++ b/src/Engine/Renderer/Renderer.hpp
@@ -64,6 +64,8 @@ namespace Engine
 	{
 		using MeshLoaderPFN = std::optional<MeshDocument>(*)(size_t);
 		MeshLoaderPFN meshLoader = nullptr;
+		using TextureLoaderPFN = std::optional<TextureDocument>(*)(size_t);
+		TextureLoaderPFN textureLoader = nullptr;
 	};
 
 	struct Renderer::InitInfo
diff --git a/src/Engine/Renderer/Typedefs.hpp b/src/Engine/Renderer/Typedefs.hpp
index f2c34df31bf14a605d36ebbcc0fa9674c8dff8d0..fd71484ef7d9889a4abc5023c185edb77941b8e2 100644
--- a/src/Engine/Renderer/Typedefs.hpp
+++ b/src/Engine/Renderer/Typedefs.hpp
@@ -23,6 +23,7 @@ namespace Engine
 		struct InitInfo;
 
 		class MeshDocument;
+		class TextureDocument;
 
 
 		enum class API;