Compare commits

..

3 Commits

Author SHA1 Message Date
628225af45 Asset explorer showing files
After loading a project the asset explorer now show all the project files.
2022-11-11 13:10:05 +01:00
b5db500d48 Import / Export Meshes 2022-11-10 21:51:11 +01:00
f7a85d53ab Editor Asset explorer setup 2022-11-10 21:50:27 +01:00
21 changed files with 350 additions and 17 deletions

1
.gitattributes vendored
View File

@ -1,2 +1,3 @@
*.png filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text
*.webp filter=lfs diff=lfs merge=lfs -text *.webp filter=lfs diff=lfs merge=lfs -text
*.xcf filter=lfs diff=lfs merge=lfs -text

BIN
Editor/rsc/AssetIcon.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Editor/rsc/AssetIcon.xcf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Editor/rsc/FodlerIcon.xcf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Editor/rsc/FolderIcon.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,46 @@
#pragma once
#include <filesystem>
#include <string>
#include "../../YoggieEngine/src/YoggieEngine.h"
enum class ASSET_TYPE {
Unknown = -1,
Mesh,
Texture,
Material
};
class Asset {
public:
Asset(const char* name): name(name) {}
virtual ASSET_TYPE GetType() { return ASSET_TYPE::Unknown; }
const char* GetName() const { return name.c_str(); }
bool isFolder = false ;
protected:
std::string name;
};
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:
};

View File

@ -0,0 +1,149 @@
#include "AssetManager.h"
#include "../../YoggieEngine/src/AssetManager/ModelImporter.h"
#include <iostream>
#include <fstream>
#include <spdlog/spdlog.h>
std::vector<Asset> AssetManager::assets;
std::filesystem::path AssetManager::currentPath;
void AssetManager::Init()
{
assets = std::vector<Asset>();
currentPath = std::filesystem::path(".");
}
void AssetManager::BuildAssetView()
{
if (currentPath.empty()) {
return;
}
for (auto& dir_entry : std::filesystem::directory_iterator(currentPath))
{
auto asset = Asset(dir_entry.path().filename().string().c_str());
if (dir_entry.is_directory()) {
asset.isFolder = true;
}
assets.push_back(asset);
}
}
void AssetManager::setAssetPath(std::filesystem::path path)
{
currentPath = path;
}
YoggieEngine::Mesh* AssetManager::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;
}
YoggieEngine::Renderable* AssetManager::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.c_str(), 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;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <vector>
#include "Asset.h"
class AssetManager {
public:
static void Init();
static void BuildAssetView();
static void setAssetPath(std::filesystem::path path);
static YoggieEngine::Mesh* LoadFromAssetFile(const std::filesystem::path assetPath);
static YoggieEngine::Renderable* LoadFromSource(const std::filesystem::path srcPath, const std::filesystem::path assetFolder);
static std::vector<Asset> assets ;
private:
static std::filesystem::path currentPath;
};

View File

@ -1,4 +1,7 @@
#pragma once #pragma once
#include "Project/Project.h"
struct EditorContext { struct EditorContext {
std::shared_ptr<Project> CurrentProject; std::shared_ptr<Project> CurrentProject;

View File

@ -3,7 +3,7 @@
#include "../../YoggieEngine/src/Graphics/Memory/Framebuffer.h" #include "../../YoggieEngine/src/Graphics/Memory/Framebuffer.h"
#include "../../YoggieEngine/src/PerfCounter.h" #include "../../YoggieEngine/src/PerfCounter.h"
#include "../../YoggieEngine/src/Scene/Entity.h" #include "../../YoggieEngine/src/Scene/Entity.h"
#include "Project.h" #include "Project/Project.h"
class EditorRuntime : public ApplicationRuntime { class EditorRuntime : public ApplicationRuntime {
@ -31,7 +31,6 @@ public:
auto& rendercube2 = cube2.AddComponent<Render3DComponent>(); auto& rendercube2 = cube2.AddComponent<Render3DComponent>();
rendercube2.mesh = *(Model->renderable->mesh); rendercube2.mesh = *(Model->renderable->mesh);
// create an ambient light source // create an ambient light source
auto AmbientLight = MainScene.AddEntity("AmbientLight"); auto AmbientLight = MainScene.AddEntity("AmbientLight");
auto light = AmbientLight.AddComponent<LightComponent>(); auto light = AmbientLight.AddComponent<LightComponent>();

View File

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include "../../YoggieEngine/src/Scene/Components.h" #include "../../YoggieEngine/src/Scene/Components.h"
#include "../../YoggieEngine/src/Scene/Entity.h" #include "../../YoggieEngine/src/Scene/Entity.h"
#include "../AssetManagement/AssetManager.h"
class Editor; class Editor;
void ComponentView(const std::string& componentName, voidFunction func) void ComponentView(const std::string& componentName, voidFunction func)
@ -169,7 +170,59 @@ void Console() {
} }
void AssetsFinder() { void AssetsFinder() {
static YoggieEngine::Texture folderIcon ("rsc/folderIcon.png");
static YoggieEngine::Texture AssetIcon("rsc/assetIcon.png");
static int iconSize = 60;
ImGui::Begin("Asset-Finder", false); ImGui::Begin("Asset-Finder", false);
ImGui::Dummy(ImVec2{ 128, 128 }); ImGui::DragInt("IconSize", &iconSize, 1, 30, 90);
if (ImGui::BeginTable("##resources", 3))
{
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 1.f, 1.f, 0.2f));
int row = 0;
int column = 0 ;
for (auto& asset : AssetManager::assets) {
if (column % 3 == 0) {
ImGui::TableNextRow();
column = 0;
row++;
}
ImGui::TableSetColumnIndex(column);
if (asset.isFolder) {
ImGui::ImageButton(
(ImTextureID)folderIcon.GetID(),
ImVec2{ (float)iconSize,(float)iconSize });
ImGui::Text(asset.GetName(), row);
}
else {
ImGui::ImageButton(
(ImTextureID)AssetIcon.GetID(),
ImVec2{ (float)iconSize, (float)iconSize });
ImGui::Text(asset.GetName(), row);
}
column++;
}
ImGui::PopStyleColor(3);
ImGui::EndTable();
}
ImGui::End(); ImGui::End();
} }

View File

@ -10,10 +10,11 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include "UI/Widgets.h" #include "UI/Widgets.h"
#include "Project.h" #include "Project/Project.h"
#include "SceneSerializer.h" #include "SceneSerializer.h"
#include "EditorContext.h" #include "EditorContext.h"
#include "SceneRuntime.h" #include "SceneRuntime.h"
#include "AssetManagement/AssetManager.h"
const unsigned int MS_PER_UPDATE = 2; const unsigned int MS_PER_UPDATE = 2;
@ -23,7 +24,6 @@ public:
void Run() override void Run() override
{ {
BarinkWindow mainWindow = BarinkWindow(1200, 700); BarinkWindow mainWindow = BarinkWindow(1200, 700);
InputSystem = new InputManager(); InputSystem = new InputManager();
renderer = new Renderer(); renderer = new Renderer();
@ -36,6 +36,7 @@ public:
double previous = glfwGetTime(); double previous = glfwGetTime();
double lag = 0.0; double lag = 0.0;
AssetManager::Init();
renderer->Prepare(activeRuntime.MainScene); renderer->Prepare(activeRuntime.MainScene);
while (!mainWindow.WindowShouldClose()) while (!mainWindow.WindowShouldClose())
@ -46,6 +47,7 @@ public:
previous = current; previous = current;
lag += elapsed; lag += elapsed;
InputSystem->PollEvents(); InputSystem->PollEvents();
while (lag >= MS_PER_UPDATE) while (lag >= MS_PER_UPDATE)
@ -138,6 +140,8 @@ public:
switch (result) { switch (result) {
case(NFD_OKAY): case(NFD_OKAY):
Project::LoadProject(path, activeRuntime.CurrentProject); Project::LoadProject(path, activeRuntime.CurrentProject);
AssetManager::setAssetPath(activeRuntime.CurrentProject.get()->GetProjectDirectory());
AssetManager::BuildAssetView();
break; break;
case(NFD_CANCEL): case(NFD_CANCEL):
break; break;
@ -213,10 +217,44 @@ public:
} }
if (ImGui::MenuItem("Add Entity")) { if (ImGui::MenuItem("Add Entity"))
{
activeRuntime.MainScene.AddEntity("New 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, activeRuntime.CurrentProject.get()->GetProjectDirectory() / "Assets");
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(); ImGui::EndMenu();
} }
@ -252,6 +290,7 @@ private:
char* savePath = nullptr; char* savePath = nullptr;
char* scenePath = nullptr; char* scenePath = nullptr;
char* openScenePath = nullptr; char* openScenePath = nullptr;
char* modelImportPath = nullptr;
}; };

View File

@ -15,7 +15,7 @@ namespace YoggieEngine {
glGenTextures(1, &Id); glGenTextures(1, &Id);
glBindTexture(GL_TEXTURE_2D, Id); glBindTexture(GL_TEXTURE_2D, Id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

View File

@ -6,7 +6,7 @@ namespace YoggieEngine {
void Bind(); void Bind();
void Unbind(); void Unbind();
const unsigned int GetID() const { return Id; }
private: private:
unsigned int Id; unsigned int Id;
}; };

View File

@ -88,14 +88,11 @@ namespace YoggieEngine {
ScrollEvent.name = "SCROLL"; ScrollEvent.name = "SCROLL";
InputSystem.EmitEvent(ScrollEvent); InputSystem.EmitEvent(ScrollEvent);
} }
void InputManager::attach(BarinkWindow* window) void InputManager::attach(BarinkWindow* window)
{ {
windows.push_back(window); windows.push_back(window);
// Attach callbacks // Attach callbacks
@ -107,8 +104,6 @@ namespace YoggieEngine {
this->Subscribe( (EventListener&)(*window)); this->Subscribe( (EventListener&)(*window));
} }
InputManager::InputManager() : EventEmitter () InputManager::InputManager() : EventEmitter ()

View File

@ -57,7 +57,6 @@ namespace YoggieEngine {
} }
BarinkWindow::~BarinkWindow() { BarinkWindow::~BarinkWindow() {
glfwTerminate(); glfwTerminate();
} }

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
typedef uint64_t ENTITY_UUID;
namespace YoggieEngine { namespace YoggieEngine {
class Scene; class Scene;
class Entity { class Entity {

View File

@ -0,0 +1,16 @@
#pragma once
#include <cstdint>
class UUID {
public:
static uint64_t Generate()
{
return ++last;
}
private:
static uint64_t last ;
};