Import / Export Meshes
This commit is contained in:
		
							
								
								
									
										47
									
								
								Editor/src/AssetManagement/Asset.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Editor/src/AssetManagement/Asset.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "../../YoggieEngine/src/Graphics/Primitives/Mesh.h"
 | 
			
		||||
#include "../../YoggieEngine/src/Graphics/Primitives/Texture.h"
 | 
			
		||||
#include "../../../YoggieEngine/src/Scene/UUID.h"
 | 
			
		||||
typedef uint64_t ASSET_UUID ;
 | 
			
		||||
 | 
			
		||||
enum class ASSET_TYPE {
 | 
			
		||||
	Unknown = -1,
 | 
			
		||||
	Mesh,
 | 
			
		||||
	Texture,
 | 
			
		||||
	Material
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Asset {
 | 
			
		||||
public:
 | 
			
		||||
	Asset(const char* name): ID(UUID::Generate()), name(std::string(name)) {}
 | 
			
		||||
	virtual ASSET_TYPE GetType() = 0;
 | 
			
		||||
protected:
 | 
			
		||||
	std::string& name;
 | 
			
		||||
	ASSET_UUID ID;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MeshAsset : Asset {
 | 
			
		||||
public:
 | 
			
		||||
	MeshAsset(YoggieEngine::Mesh mesh) : Asset("New MeshAsset"), mesh(mesh) {}
 | 
			
		||||
	ASSET_TYPE  GetType() override { return ASSET_TYPE::Mesh; }
 | 
			
		||||
private:
 | 
			
		||||
	YoggieEngine::Mesh& mesh;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TextureAsset : Asset {
 | 
			
		||||
public:
 | 
			
		||||
	TextureAsset (YoggieEngine::Texture texture): Asset("New TextureAsset"), texture(texture) {}
 | 
			
		||||
	ASSET_TYPE GetType() override { return ASSET_TYPE::Texture; }
 | 
			
		||||
private:
 | 
			
		||||
	YoggieEngine::Texture& texture;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MaterialAsset : Asset {
 | 
			
		||||
public:
 | 
			
		||||
	MaterialAsset ()  : Asset("New MaterialAsset"){}
 | 
			
		||||
	ASSET_TYPE GetType() override { return ASSET_TYPE::Material; }
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										118
									
								
								Editor/src/AssetManagement/AssetManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								Editor/src/AssetManagement/AssetManager.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,118 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <filesystem>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
#include "../../../YoggieEngine/src/Graphics/Renderable.h"
 | 
			
		||||
#include "../../../YoggieEngine/src/AssetManager/ModelImporter.h"
 | 
			
		||||
#include <spdlog/spdlog.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
class AssetManager {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	static YoggieEngine::Mesh* LoadFromAssetFile(const std::filesystem::path assetPath )
 | 
			
		||||
	{
 | 
			
		||||
		YoggieEngine::Mesh imported;
 | 
			
		||||
 | 
			
		||||
		std::ifstream AssetFile;
 | 
			
		||||
		AssetFile.open(assetPath, std::ios::binary);
 | 
			
		||||
		if (AssetFile.is_open()) {
 | 
			
		||||
 | 
			
		||||
			char* Header = (char*) malloc(8);
 | 
			
		||||
			unsigned long long  Vsize = 0;
 | 
			
		||||
			uint32_t Vnum = 0;
 | 
			
		||||
			uint32_t Enum = 0;
 | 
			
		||||
 | 
			
		||||
			// Read header 
 | 
			
		||||
			AssetFile.read(Header, 8);
 | 
			
		||||
			AssetFile.read((char*)&Vsize, sizeof(unsigned long long ));
 | 
			
		||||
			AssetFile.read((char*)&Vnum, sizeof(uint32_t));
 | 
			
		||||
			AssetFile.read((char*)&Enum, sizeof(uint32_t));
 | 
			
		||||
 | 
			
		||||
			// print Header info 
 | 
			
		||||
			std::cout << "File has header: " << Header << std::endl;
 | 
			
		||||
			std::cout << "Vertex size: " << Vsize << std::endl;
 | 
			
		||||
			std::cout << "Number of Vertices: " << Vnum << std::endl;
 | 
			
		||||
			std::cout << "Number of Elements: " << Enum << std::endl;
 | 
			
		||||
			free(Header);
 | 
			
		||||
 | 
			
		||||
			// Load Vertices (Vertex + UV )
 | 
			
		||||
			imported.vertices = std::vector < YoggieEngine::Vertex>();
 | 
			
		||||
			for (int i = 0; i < Vnum; i++) 
 | 
			
		||||
			{
 | 
			
		||||
				YoggieEngine::Vertex data = YoggieEngine::Vertex();
 | 
			
		||||
				AssetFile.read((char*) & data, Vsize);
 | 
			
		||||
 | 
			
		||||
				imported.vertices.push_back(data);
 | 
			
		||||
			
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// skip x bytes 
 | 
			
		||||
			AssetFile.ignore(sizeof(char) * 3);
 | 
			
		||||
 | 
			
		||||
			// Load Elements
 | 
			
		||||
			imported.elements = std::vector<unsigned int>();
 | 
			
		||||
			for (int i = 0; i < Enum; i++) {
 | 
			
		||||
				unsigned int data = 0;
 | 
			
		||||
				AssetFile.read((char*)&data, sizeof(unsigned int));
 | 
			
		||||
				imported.elements.push_back(data);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			std::cout << "Failed ot open mesh " << std::endl;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		return nullptr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static YoggieEngine::Renderable* LoadFromSource(const std::filesystem::path srcPath , const std::filesystem::path assetFolder ) {
 | 
			
		||||
		auto model = (YoggieEngine::ModelImporter()).Import(srcPath.string());
 | 
			
		||||
		YoggieEngine::Mesh* exportMesh = model->renderable->mesh;
 | 
			
		||||
		std::filesystem::path MeshFileName = assetFolder / srcPath.filename().replace_extension( ".mesh");
 | 
			
		||||
		std::cout << "Save path: " << MeshFileName << std::endl;
 | 
			
		||||
 | 
			
		||||
		std::ofstream meshAsset;
 | 
			
		||||
		meshAsset.open(MeshFileName, std::ios::binary );
 | 
			
		||||
		if (meshAsset.is_open()) {
 | 
			
		||||
 | 
			
		||||
			// write a header
 | 
			
		||||
			static const char* HEADER = "MESH";
 | 
			
		||||
			meshAsset.write(HEADER, sizeof(HEADER));
 | 
			
		||||
			auto Vsize = sizeof(YoggieEngine::Vertex);
 | 
			
		||||
			std::cout << "size of vertex: " << Vsize << std::endl;
 | 
			
		||||
			std::cout << "Addr of vSize: " << &Vsize << std::endl;
 | 
			
		||||
			auto Vnum = exportMesh->vertices.size();
 | 
			
		||||
			auto Enum = exportMesh->elements.size();
 | 
			
		||||
 | 
			
		||||
			meshAsset.write((char*) & Vsize, sizeof(unsigned long long ) );
 | 
			
		||||
			meshAsset.write((char*)&Vnum, sizeof(uint32_t));
 | 
			
		||||
			meshAsset.write((char*)&Enum, sizeof(uint32_t));
 | 
			
		||||
			// write all vertices 
 | 
			
		||||
			for (auto vertice : exportMesh->vertices)
 | 
			
		||||
			{
 | 
			
		||||
				meshAsset.write((char*)&vertice, sizeof(vertice));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// write 3 x 0 byte
 | 
			
		||||
			meshAsset.write((const char*)"\0\0\0", sizeof(char) * 3);
 | 
			
		||||
 | 
			
		||||
			// write all indices 
 | 
			
		||||
			for (auto index : exportMesh->elements) {
 | 
			
		||||
				meshAsset.write((char*)&index, sizeof(index));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			meshAsset.close();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			spdlog::error("Failed to create/open mesh file.");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return model->renderable;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
@ -10,10 +10,11 @@
 | 
			
		||||
#include <glm/gtc/matrix_transform.hpp>
 | 
			
		||||
 | 
			
		||||
#include "UI/Widgets.h"
 | 
			
		||||
#include "Project.h"
 | 
			
		||||
#include "Project/Project.h"
 | 
			
		||||
#include "SceneSerializer.h"
 | 
			
		||||
#include "EditorContext.h"
 | 
			
		||||
#include "SceneRuntime.h"
 | 
			
		||||
#include "AssetManagement/AssetManager.h"
 | 
			
		||||
 | 
			
		||||
const unsigned int MS_PER_UPDATE = 2;
 | 
			
		||||
 | 
			
		||||
@ -23,7 +24,6 @@ public:
 | 
			
		||||
    void Run() override
 | 
			
		||||
    {
 | 
			
		||||
        BarinkWindow mainWindow = BarinkWindow(1200, 700);
 | 
			
		||||
        
 | 
			
		||||
        InputSystem = new InputManager();
 | 
			
		||||
        renderer = new Renderer();
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,7 @@ public:
 | 
			
		||||
            previous = current;
 | 
			
		||||
            lag += elapsed;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            InputSystem->PollEvents();
 | 
			
		||||
 | 
			
		||||
            while (lag >= MS_PER_UPDATE) 
 | 
			
		||||
@ -213,10 +214,44 @@ public:
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ImGui::MenuItem("Add Entity")) {
 | 
			
		||||
            if (ImGui::MenuItem("Add Entity"))
 | 
			
		||||
            {
 | 
			
		||||
                activeRuntime.MainScene.AddEntity("New Entity");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ImGui::MenuItem("Import Model")) 
 | 
			
		||||
            {
 | 
			
		||||
                auto result = NFD_OpenDialog(  "obj,fbx,gltf" , NULL, &modelImportPath);
 | 
			
		||||
                switch (result) {
 | 
			
		||||
                case(NFD_OKAY):
 | 
			
		||||
                    // Import Model
 | 
			
		||||
                    AssetManager::LoadFromSource(modelImportPath, ".");
 | 
			
		||||
                    break;
 | 
			
		||||
                case(NFD_CANCEL):
 | 
			
		||||
                    break;
 | 
			
		||||
                case(NFD_ERROR):
 | 
			
		||||
                    std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ImGui::MenuItem("Import MeshAsset (temp)")) 
 | 
			
		||||
            {
 | 
			
		||||
                auto result = NFD_OpenDialog("mesh", NULL, &modelImportPath);
 | 
			
		||||
                switch (result) {
 | 
			
		||||
                case(NFD_OKAY):
 | 
			
		||||
                    AssetManager::LoadFromAssetFile(modelImportPath);
 | 
			
		||||
                    break;
 | 
			
		||||
                case(NFD_CANCEL):
 | 
			
		||||
                    break;
 | 
			
		||||
                case(NFD_ERROR):
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            ImGui::EndMenu();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -252,6 +287,7 @@ private:
 | 
			
		||||
    char* savePath = nullptr;
 | 
			
		||||
    char* scenePath = nullptr;
 | 
			
		||||
    char* openScenePath = nullptr;
 | 
			
		||||
    char* modelImportPath = nullptr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user