Starting on prefabs
This commit is contained in:
parent
c3ce41307a
commit
3ec06233e7
13
.vscode/c_cpp_properties.json
vendored
13
.vscode/c_cpp_properties.json
vendored
@ -16,19 +16,6 @@
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
},
|
||||
{
|
||||
"name": "main",
|
||||
"includePath": [
|
||||
"${default}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.22621.0",
|
||||
"compilerPath": "cl.exe"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
177
.vscode/settings.json
vendored
177
.vscode/settings.json
vendored
@ -1,88 +1,93 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.pyx": "python",
|
||||
"*.js": "javascript",
|
||||
"*.c": "c",
|
||||
"*.scene": "yaml",
|
||||
"*.cene": "yaml",
|
||||
"*.h": "cpp",
|
||||
"memory": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"fstream": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"*.inc": "cpp",
|
||||
"future": "cpp",
|
||||
"any": "cpp",
|
||||
"ranges": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"source_location": "cpp",
|
||||
"csignal": "cpp"
|
||||
}
|
||||
"files.associations": {
|
||||
"*.pyx": "python",
|
||||
"*.js": "javascript",
|
||||
"*.c": "c",
|
||||
"*.scene": "yaml",
|
||||
"*.cene": "yaml",
|
||||
"*.h": "cpp",
|
||||
"memory": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"fstream": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"*.inc": "cpp",
|
||||
"future": "cpp",
|
||||
"any": "cpp",
|
||||
"ranges": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"source_location": "cpp",
|
||||
"csignal": "cpp"
|
||||
},
|
||||
// Use MS IntelliSense so IntelliCode works
|
||||
"C_Cpp.intelliSenseEngine": "default",
|
||||
"C_Cpp.limitSymbolsToIncludedHeaders": true,
|
||||
"C_Cpp.exploreMode": "lightweight",
|
||||
|
||||
}
|
42
imgui.ini
42
imgui.ini
@ -10,24 +10,24 @@ Collapsed=1
|
||||
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,19
|
||||
Size=1280,701
|
||||
Size=1920,1158
|
||||
Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=913,19
|
||||
Size=367,202
|
||||
Pos=1553,19
|
||||
Size=367,659
|
||||
Collapsed=0
|
||||
DockId=0x00000018,0
|
||||
|
||||
[Window][Scene Tree]
|
||||
Pos=0,19
|
||||
Size=342,350
|
||||
Size=342,579
|
||||
Collapsed=0
|
||||
DockId=0x0000000F,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=344,19
|
||||
Size=567,202
|
||||
Size=1207,659
|
||||
Collapsed=0
|
||||
DockId=0x00000017,0
|
||||
|
||||
@ -36,14 +36,14 @@ Size=1280,19
|
||||
Collapsed=0
|
||||
|
||||
[Window][Performance Info]
|
||||
Pos=1094,223
|
||||
Size=186,497
|
||||
Pos=1606,680
|
||||
Size=314,497
|
||||
Collapsed=0
|
||||
DockId=0x00000016,0
|
||||
|
||||
[Window][Console]
|
||||
Pos=344,223
|
||||
Size=715,273
|
||||
Pos=344,680
|
||||
Size=1206,273
|
||||
Collapsed=0
|
||||
DockId=0x00000013,0
|
||||
|
||||
@ -54,8 +54,8 @@ Collapsed=0
|
||||
DockId=0x00000017,1
|
||||
|
||||
[Window][Profiler]
|
||||
Pos=344,498
|
||||
Size=715,222
|
||||
Pos=344,955
|
||||
Size=1206,222
|
||||
Collapsed=0
|
||||
DockId=0x00000014,0
|
||||
|
||||
@ -112,8 +112,8 @@ Collapsed=0
|
||||
DockId=0x0000000E,0
|
||||
|
||||
[Window][Audio Output]
|
||||
Pos=1061,223
|
||||
Size=31,497
|
||||
Pos=1552,680
|
||||
Size=52,497
|
||||
Collapsed=0
|
||||
DockId=0x00000012,0
|
||||
|
||||
@ -124,13 +124,23 @@ Collapsed=0
|
||||
DockId=0x0000000D,0
|
||||
|
||||
[Window][Resources]
|
||||
Pos=0,371
|
||||
Size=342,349
|
||||
Pos=0,600
|
||||
Size=342,577
|
||||
Collapsed=0
|
||||
DockId=0x00000010,0
|
||||
|
||||
[Window][Import Preview]
|
||||
Pos=351,22
|
||||
Size=550,695
|
||||
Collapsed=0
|
||||
|
||||
[Table][0x96376740,2]
|
||||
RefScale=13
|
||||
Column 0 Weight=1.0000
|
||||
Column 1 Width=120
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=X
|
||||
DockNode ID=0x00000005 Parent=0x11111111 SizeRef=989,1158 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,637 Split=Y Selected=0x12EF0F59
|
||||
|
@ -1,2 +1,4 @@
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\core\utils\Popup.cpp -o src\build\core\utils\Popup.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\editor\windows\AssetBrowser.cpp -o src\build\editor\windows\AssetBrowser.o
|
||||
[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Popup.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\AudioInfo.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o src\build\miniaudio.o src\build\ImGuizmo.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp
|
||||
[ERROR] Runtime crash
|
||||
Command 'src\build\app.exe' returned non-zero exit status 3.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,8 @@
|
||||
#include "../core/utils/AssetManager.h"
|
||||
#include "../core/audio/AudioEngine.h"
|
||||
|
||||
|
||||
|
||||
AudioPlayerComponent::AudioPlayerComponent(Object* owner)
|
||||
: Component(owner)
|
||||
{}
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "../core/utils/Logging.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class Object;
|
||||
|
||||
class Component {
|
||||
|
@ -35,6 +35,9 @@
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@ -55,6 +58,8 @@
|
||||
#include <json.hpp>
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
|
||||
static std::shared_ptr<Object> selected = nullptr;
|
||||
static bool playing = false;
|
||||
static bool lastPlaying = false;
|
||||
@ -75,6 +80,7 @@ static const std::string tempScenePath = "__tmp_scene.yaml";
|
||||
|
||||
GLFWwindow *window = nullptr;
|
||||
|
||||
|
||||
Engine::Engine()
|
||||
{
|
||||
|
||||
@ -1246,9 +1252,9 @@ void Engine::Run()
|
||||
}
|
||||
else if (previewObj && mouseReleased && hoveringViewport)
|
||||
{
|
||||
|
||||
previewObj = nullptr;
|
||||
previewUAID = 0;
|
||||
|
||||
}
|
||||
else if (previewObj && (!hoveringViewport || !draggingTexture))
|
||||
{
|
||||
|
@ -286,4 +286,6 @@ void Object::Load(const YAML::Node &node)
|
||||
AddChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "LoadingWindow.h"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
#include "../../Entitys/Object.h"
|
||||
|
||||
|
||||
|
||||
@ -170,6 +171,71 @@ const char *MiniaudioResultToString(ma_result result)
|
||||
|
||||
|
||||
|
||||
|
||||
// PrefabAssetInfo.cpp
|
||||
|
||||
PrefabAssetInfo::PrefabAssetInfo() {
|
||||
type = AssetType::Prefab;
|
||||
}
|
||||
|
||||
void PrefabAssetInfo::Save(YAML::Emitter& out) const {
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "uaid" << YAML::Value << uaid;
|
||||
out << YAML::Key << "path" << YAML::Value << path;
|
||||
out << YAML::Key << "filename" << YAML::Value << filename;
|
||||
out << YAML::Key << "filetype" << YAML::Value << filetype;
|
||||
out << YAML::Key << "type" << YAML::Value << "Prefab";
|
||||
out << YAML::Key << "hash" << YAML::Value << hash;
|
||||
out << YAML::Key << "lastModified" << YAML::Value << lastModified;
|
||||
out << YAML::Key << "loaded" << YAML::Value << loaded;
|
||||
out << YAML::Key << "prefabYAML" << YAML::Value << prefabYAML;
|
||||
|
||||
// Prefab metadata
|
||||
out << YAML::Key << "prefabName" << YAML::Value << prefabName;
|
||||
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
|
||||
void PrefabAssetInfo::Load(const YAML::Node& node) {
|
||||
uaid = node["uaid"].as<uint64_t>();
|
||||
path = node["path"].as<std::string>();
|
||||
filename = node["filename"].as<std::string>();
|
||||
filetype = node["filetype"].as<std::string>();
|
||||
hash = node["hash"].as<std::string>();
|
||||
lastModified = node["lastModified"].as<std::time_t>();
|
||||
loaded = node["loaded"].as<bool>();
|
||||
prefabYAML = node["prefabYAML"] ? node["prefabYAML"].as<std::string>() : "";
|
||||
|
||||
|
||||
if (node["prefabName"])
|
||||
prefabName = node["prefabName"].as<std::string>();
|
||||
|
||||
|
||||
ReloadFromYAML();
|
||||
}
|
||||
|
||||
void PrefabAssetInfo::ReloadFromYAML()
|
||||
{
|
||||
if (prefabYAML.empty())
|
||||
return;
|
||||
|
||||
YAML::Node root;
|
||||
try {
|
||||
root = YAML::Load(prefabYAML);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
Logger::LogError("[Prefab] YAML parse error: %s", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
prefabRoot = std::make_shared<Object>("PrefabRoot");
|
||||
prefabRoot->Load(root);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AssetManager::Init()
|
||||
{
|
||||
Logger::LogOk("AssetManager Core");
|
||||
@ -214,6 +280,9 @@ void AssetManager::LoadAssetAsync(const std::string &path, AssetType type)
|
||||
LoadImageInternal(path, uaid);
|
||||
else if (type == AssetType::Audio)
|
||||
LoadAudioInternal(path, uaid);
|
||||
else if (type == AssetType::Prefab)
|
||||
LoadPrefabInternal(path, uaid);
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::LoadImageInternal(const std::string &path, uint64_t uaid)
|
||||
@ -273,6 +342,9 @@ void AssetManager::LoadImageInternal(const std::string &path, uint64_t uaid)
|
||||
Logger::LogVerbose("[AssetManager] Loaded image: %s (%dx%d)", path.c_str(), w, h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AssetManager::LoadAudioInternal(const std::string &path, uint64_t uaid)
|
||||
{
|
||||
auto it = s_Assets.find(uaid);
|
||||
@ -302,6 +374,55 @@ void AssetManager::LoadAudioInternal(const std::string &path, uint64_t uaid)
|
||||
Logger::LogVerbose("[AssetManager] Loaded audio: %s", path.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AssetManager::LoadPrefabInternal(const std::string& path, uint64_t uaid)
|
||||
{
|
||||
// Skip if already loaded and not dirty
|
||||
auto it = s_Assets.find(uaid);
|
||||
if (it != s_Assets.end() && it->second->loaded)
|
||||
return;
|
||||
|
||||
if (!FileExists(path))
|
||||
{
|
||||
Logger::LogError("[AssetManager] Prefab file not found: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string yamlContent;
|
||||
if (!ReadTextFile(path, yamlContent))
|
||||
{
|
||||
Logger::LogError("[AssetManager] Failed to read prefab file: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
auto prefab = std::make_shared<PrefabAssetInfo>();
|
||||
prefab->uaid = uaid;
|
||||
prefab->path = path;
|
||||
prefab->filename = GetFilenameFromPath(path);
|
||||
prefab->filetype = GetFileExtension(path);
|
||||
prefab->type = AssetType::Prefab;
|
||||
prefab->prefabYAML = yamlContent;
|
||||
prefab->lastModified = GetFileLastWrite(path);
|
||||
prefab->hash = GetFileHash(path);
|
||||
prefab->loaded = true;
|
||||
|
||||
prefab->ReloadFromYAML();
|
||||
|
||||
if (!prefab->prefabRoot)
|
||||
{
|
||||
Logger::LogError("[AssetManager] Failed to deserialize prefab object: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
s_Assets[uaid] = prefab;
|
||||
|
||||
Logger::LogVerbose("[AssetManager] Loaded prefab: %s (UAID: %llu)", path.c_str(), uaid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const AssetInfo *AssetManager::GetAssetByID(uint64_t uaid)
|
||||
{
|
||||
auto it = s_Assets.find(uaid);
|
||||
|
@ -9,7 +9,15 @@
|
||||
#include <GL/glew.h>
|
||||
#include "miniaudio.h"
|
||||
|
||||
enum class AssetType { Image, Audio, Unknown };
|
||||
class Object;
|
||||
|
||||
enum class AssetType {
|
||||
Image,
|
||||
Audio,
|
||||
Prefab,
|
||||
Unknown
|
||||
};
|
||||
|
||||
|
||||
struct AssetInfo
|
||||
{
|
||||
@ -51,6 +59,25 @@ struct AudioAssetInfo : public AssetInfo
|
||||
void Load(const YAML::Node& node) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PrefabAssetInfo : public AssetInfo
|
||||
{
|
||||
std::string prefabYAML;
|
||||
std::shared_ptr<Object> prefabRoot = nullptr;
|
||||
|
||||
std::string prefabName = "Unnamed Prefab";
|
||||
|
||||
|
||||
PrefabAssetInfo();
|
||||
void Save(YAML::Emitter& out) const override;
|
||||
void Load(const YAML::Node& node) override;
|
||||
|
||||
void ReloadFromYAML(); // reparses prefabYAML into prefabRoot
|
||||
};
|
||||
|
||||
|
||||
|
||||
const char* MiniaudioResultToString(ma_result result);
|
||||
|
||||
|
||||
@ -75,4 +102,6 @@ private:
|
||||
static uint64_t GenerateUAID();
|
||||
static void LoadImageInternal(const std::string& path, uint64_t uaid);
|
||||
static void LoadAudioInternal(const std::string& path, uint64_t uaid);
|
||||
static void LoadPrefabInternal(const std::string& path, uint64_t uaid);
|
||||
|
||||
};
|
||||
|
@ -12,7 +12,7 @@
|
||||
//! Macro Fuckery my Gz
|
||||
|
||||
EngineConfig g_engineConfig{
|
||||
.version = "0.8.2",
|
||||
.version = "0.8.3",
|
||||
.gl_version = "430",
|
||||
.gl_maxLight = 512,
|
||||
.settings = UserSettings{}
|
||||
|
@ -13,14 +13,16 @@
|
||||
//TODO: Make this all memroy safe.
|
||||
|
||||
static std::unordered_map<FileDialogType, const char*> filters = {
|
||||
{ FileDialogType::Images, "Image Files\0*.png;*.jpg;*.jpeg;*.bmp;*.tga;*.gif;*.dds\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Scenes, "CreateScene Files\0*.cene;*.cscene;*.yaml\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Audio, "Audio Files\0*.mp3;*.wav;*.ogg;*.flac;*.aac\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Scripts, "Lua Scripts\0*.lua\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Shaders, "Shader Files\0*.glsl;*.vert;*.frag;*.hlsl\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Fonts, "Font Files\0*.ttf;*.otf;*.fnt\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Models, "3D Models\0*.obj;*.fbx;*.gltf;*.dae\0All Files\0*.*\0" },
|
||||
{ FileDialogType::All, "All Files\0*.*\0" }
|
||||
{ FileDialogType::Images, "Image Files\0*.png;*.jpg;*.jpeg;*.bmp;*.tga;*.gif;*.dds\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Scenes, "CreateScene Files\0*.cene;*.cscene;*.yaml\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Prefabs, "Prefab Files\0*.cpfb\0All Files\0*.*\0" },
|
||||
{ FileDialogType::AssetPacks, "Asset Pack Files\0*.cpack;*.capk\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Audio, "Audio Files\0*.mp3;*.wav;*.ogg;*.flac;*.aac\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Scripts, "Lua Scripts\0*.lua\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Shaders, "Shader Files\0*.glsl;*.vert;*.frag;*.hlsl\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Fonts, "Font Files\0*.ttf;*.otf;*.fnt\0All Files\0*.*\0" },
|
||||
{ FileDialogType::Models, "3D Models\0*.obj;*.fbx;*.gltf;*.dae\0All Files\0*.*\0" },
|
||||
{ FileDialogType::All, "All Files\0*.*\0" }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4,17 +4,21 @@
|
||||
|
||||
|
||||
enum class FileDialogType {
|
||||
Images,
|
||||
Scenes,
|
||||
Audio,
|
||||
Scripts,
|
||||
Shaders,
|
||||
Fonts,
|
||||
Models,
|
||||
All
|
||||
Images, // .png, .jpg, .bmp, etc.
|
||||
Scenes, // .cene
|
||||
Prefabs, // .cpfb
|
||||
AssetPacks, // .cpack, .capk
|
||||
Audio, // .wav, .mp3, .ogg
|
||||
Scripts, // .lua, .py
|
||||
Shaders, // .vert, .frag, .glsl
|
||||
Fonts, // .ttf, .otf
|
||||
Models, // .obj, .fbx, .gltf, etc.
|
||||
All
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
std::string OpenFileDialog(FileDialogType type);
|
||||
std::string SaveFileDialog(FileDialogType type);
|
||||
std::string CreateFileDialog(FileDialogType type);
|
||||
|
@ -6,6 +6,11 @@
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
// here so i only need to include once.
|
||||
@ -76,4 +81,40 @@ inline std::string GetFileExtension(const std::string &path)
|
||||
if (dot == std::string::npos)
|
||||
return "";
|
||||
return path.substr(dot + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline std::string GetFileExtension_Name(const std::string &path)
|
||||
{
|
||||
size_t dot = path.find_last_of('.');
|
||||
if (dot == std::string::npos || dot == path.length() - 1)
|
||||
return "";
|
||||
|
||||
std::string ext = path.substr(dot + 1);
|
||||
|
||||
// Convert to lowercase
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
|
||||
inline bool FileExists(const std::string& path)
|
||||
{
|
||||
return std::filesystem::exists(path) && std::filesystem::is_regular_file(path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline bool ReadTextFile(const std::string& path, std::string& out)
|
||||
{
|
||||
std::ifstream file(path);
|
||||
if (!file.is_open())
|
||||
return false;
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
out = buffer.str();
|
||||
return true;
|
||||
}
|
||||
|
@ -13,6 +13,9 @@ static int sortMode = 0; // 0 = Name, 1 = Type, 2 = UAID
|
||||
static bool showImages = true;
|
||||
static bool showAudio = true;
|
||||
|
||||
static std::vector<std::pair<std::string, AssetType>> pendingImports;
|
||||
static bool showImportPopup = false;
|
||||
|
||||
void ShowAssetBrowser()
|
||||
{
|
||||
PROFILE_ENGINE_SCOPE("Editor::AssetBrowser");
|
||||
@ -20,50 +23,35 @@ void ShowAssetBrowser()
|
||||
if (!g_engineConfig.settings.show_asset_window)
|
||||
return;
|
||||
|
||||
// Open modal popup if needed
|
||||
if (showImportPopup)
|
||||
ImGui::OpenPopup("Import Preview");
|
||||
|
||||
ImGui::Begin("Resources");
|
||||
|
||||
// Top bar layout
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 4));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 6));
|
||||
|
||||
// Load Buttons
|
||||
if (ImGui::Button("Load Images"))
|
||||
if (ImGui::Button("Import Assets"))
|
||||
{
|
||||
std::vector<std::string> paths = OpenMultipleFilesDialog(FileDialogType::Images);
|
||||
std::vector<std::string> paths = OpenMultipleFilesDialog(FileDialogType::All);
|
||||
if (!paths.empty())
|
||||
{
|
||||
LoadingWindow loader;
|
||||
loader.Create("Loading Images...");
|
||||
pendingImports.clear();
|
||||
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
for (const auto &path : paths)
|
||||
{
|
||||
const std::string &path = paths[i];
|
||||
loader.Update("Loading Image", path, static_cast<float>(i + 1) / paths.size());
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||
std::string ext = GetFileExtension_Name(path);
|
||||
AssetType type = AssetType::Unknown;
|
||||
|
||||
if (ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "bmp" || ext == "tga" || ext == "gif" || ext == "dds")
|
||||
type = AssetType::Image;
|
||||
else if (ext == "wav" || ext == "mp3" || ext == "ogg" || ext == "flac" || ext == "aac")
|
||||
type = AssetType::Audio;
|
||||
else if (ext == "cpfb")
|
||||
type = AssetType::Prefab;
|
||||
|
||||
pendingImports.emplace_back(path, type);
|
||||
}
|
||||
|
||||
loader.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Load Audio"))
|
||||
{
|
||||
std::vector<std::string> paths = OpenMultipleFilesDialog(FileDialogType::Audio);
|
||||
if (!paths.empty())
|
||||
{
|
||||
LoadingWindow loader;
|
||||
loader.Create("Loading Audio...");
|
||||
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
{
|
||||
const std::string &path = paths[i];
|
||||
loader.Update("Loading Audio", path, static_cast<float>(i + 1) / paths.size());
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Audio);
|
||||
}
|
||||
|
||||
loader.Destroy();
|
||||
showImportPopup = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +60,6 @@ void ShowAssetBrowser()
|
||||
if (ImGui::Button("Filters / Sort"))
|
||||
ImGui::OpenPopup("AssetBrowserFilterPopup");
|
||||
|
||||
// Filters Popup
|
||||
if (ImGui::BeginPopup("AssetBrowserFilterPopup"))
|
||||
{
|
||||
ImGui::Text("Sort By:");
|
||||
@ -93,59 +80,43 @@ void ShowAssetBrowser()
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Search field (spaced below buttons)
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
char buffer[256] = {};
|
||||
strncpy(buffer, assetSearchQuery.c_str(), sizeof(buffer) - 1);
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::InputTextWithHint("##Search", "Search", buffer, sizeof(buffer)))
|
||||
{
|
||||
assetSearchQuery = buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::BeginChild("##AssetScroll", ImVec2(0, 0), true);
|
||||
|
||||
const float padding = 8.0f;
|
||||
const float thumbnailSize = 64.0f;
|
||||
const float cellSize = thumbnailSize + padding;
|
||||
|
||||
float padding = 8.0f;
|
||||
float thumbnailSize = 64.0f;
|
||||
float cellSize = thumbnailSize + padding;
|
||||
float availWidth = ImGui::GetContentRegionAvail().x;
|
||||
int columns = static_cast<int>(availWidth / cellSize);
|
||||
if (columns < 1)
|
||||
columns = 1;
|
||||
|
||||
ImGui::Columns(columns, nullptr, false);
|
||||
|
||||
// Collect, filter and sort assets
|
||||
std::vector<const AssetInfo *> sortedAssets;
|
||||
for (const auto &[uaid, asset] : AssetManager::GetAllAssets())
|
||||
{
|
||||
if (!asset || !asset->loaded)
|
||||
continue;
|
||||
|
||||
if (!assetSearchQuery.empty() &&
|
||||
asset->filename.find(assetSearchQuery) == std::string::npos &&
|
||||
asset->path.find(assetSearchQuery) == std::string::npos)
|
||||
continue;
|
||||
|
||||
if ((asset->type == AssetType::Image && !showImages) ||
|
||||
(asset->type == AssetType::Audio && !showAudio))
|
||||
continue;
|
||||
|
||||
sortedAssets.push_back(asset.get());
|
||||
}
|
||||
|
||||
std::sort(sortedAssets.begin(), sortedAssets.end(), [](const AssetInfo *a, const AssetInfo *b)
|
||||
{
|
||||
switch (sortMode)
|
||||
{
|
||||
switch (sortMode) {
|
||||
case 0: return sortAscending ? a->filename < b->filename : a->filename > b->filename;
|
||||
case 1: return sortAscending ? a->type < b->type : a->type > b->type;
|
||||
case 2: return sortAscending ? a->uaid < b->uaid : a->uaid > b->uaid;
|
||||
@ -153,38 +124,34 @@ void ShowAssetBrowser()
|
||||
} });
|
||||
|
||||
int idx = 0;
|
||||
for (const AssetInfo *baseAsset : sortedAssets)
|
||||
for (const AssetInfo *asset : sortedAssets)
|
||||
{
|
||||
ImGui::PushID(idx++);
|
||||
std::string displayName = GetFilenameFromPath(baseAsset->path);
|
||||
std::string displayName = GetFilenameFromPath(asset->path);
|
||||
|
||||
if (baseAsset->type == AssetType::Image)
|
||||
if (asset->type == AssetType::Image)
|
||||
{
|
||||
const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(baseAsset);
|
||||
if (!imageAsset)
|
||||
const auto *image = dynamic_cast<const ImageAssetInfo *>(asset);
|
||||
if (!image)
|
||||
{
|
||||
ImGui::PopID();
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui::Image((ImTextureID)(intptr_t)imageAsset->textureID,
|
||||
ImVec2(thumbnailSize, thumbnailSize));
|
||||
|
||||
ImGui::Image((ImTextureID)(intptr_t)image->textureID, ImVec2(thumbnailSize, thumbnailSize));
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
||||
{
|
||||
ImGui::SetDragDropPayload("ASSET_TEXTURE", &baseAsset->uaid, sizeof(uint64_t));
|
||||
ImGui::SetDragDropPayload("ASSET_TEXTURE", &asset->uaid, sizeof(uint64_t));
|
||||
ImGui::Text("%s", displayName.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
else if (baseAsset->type == AssetType::Audio)
|
||||
else if (asset->type == AssetType::Audio)
|
||||
{
|
||||
std::string buttonLabel = baseAsset->filetype.empty() ? "Audio" : baseAsset->filetype;
|
||||
ImGui::Button(buttonLabel.c_str(), ImVec2(thumbnailSize, thumbnailSize));
|
||||
|
||||
ImGui::Button(asset->filetype.empty() ? "Audio" : asset->filetype.c_str(), ImVec2(thumbnailSize, thumbnailSize));
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
||||
{
|
||||
ImGui::SetDragDropPayload("ASSET_AUDIO", &baseAsset->uaid, sizeof(uint64_t));
|
||||
ImGui::SetDragDropPayload("ASSET_AUDIO", &asset->uaid, sizeof(uint64_t));
|
||||
ImGui::Text("%s", displayName.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
@ -198,23 +165,17 @@ void ShowAssetBrowser()
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Path: %s", baseAsset->path.c_str());
|
||||
ImGui::Text("UAID: %llu", baseAsset->uaid);
|
||||
|
||||
if (baseAsset->type == AssetType::Image)
|
||||
ImGui::Text("Path: %s", asset->path.c_str());
|
||||
ImGui::Text("UAID: %llu", asset->uaid);
|
||||
if (asset->type == AssetType::Image)
|
||||
{
|
||||
const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(baseAsset);
|
||||
if (imageAsset)
|
||||
auto *image = dynamic_cast<const ImageAssetInfo *>(asset);
|
||||
if (image)
|
||||
{
|
||||
ImGui::Text("Texture ID: %u", imageAsset->textureID);
|
||||
ImGui::Text("Size: (%.0f, %.0f)", imageAsset->size.x, imageAsset->size.y);
|
||||
ImGui::Text("Texture ID: %u", image->textureID);
|
||||
ImGui::Text("Size: (%.0f, %.0f)", image->size.x, image->size.y);
|
||||
}
|
||||
}
|
||||
else if (baseAsset->type == AssetType::Audio)
|
||||
{
|
||||
ImGui::Text("Audio file");
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
@ -222,23 +183,15 @@ void ShowAssetBrowser()
|
||||
{
|
||||
if (ImGui::MenuItem("Unload"))
|
||||
{
|
||||
Logger::LogInfo("[AssetBrowser] Unloaded: %s", baseAsset->path.c_str());
|
||||
AssetManager::UnloadAsset(baseAsset->uaid);
|
||||
AssetManager::UnloadAsset(asset->uaid);
|
||||
ImGui::EndPopup();
|
||||
ImGui::PopID();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Copy Path"))
|
||||
{
|
||||
ImGui::SetClipboardText(baseAsset->path.c_str());
|
||||
}
|
||||
|
||||
ImGui::SetClipboardText(asset->path.c_str());
|
||||
if (ImGui::MenuItem("Copy UAID"))
|
||||
{
|
||||
ImGui::SetClipboardText(std::to_string(baseAsset->uaid).c_str());
|
||||
}
|
||||
|
||||
ImGui::SetClipboardText(std::to_string(asset->uaid).c_str());
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
@ -250,4 +203,83 @@ void ShowAssetBrowser()
|
||||
ImGui::Columns(1);
|
||||
ImGui::EndChild();
|
||||
ImGui::End();
|
||||
|
||||
if (ImGui::BeginPopupModal("Import Preview", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize))
|
||||
{
|
||||
ImGui::TextWrapped("Review and confirm asset imports. Adjust type if needed.");
|
||||
ImGui::Spacing();
|
||||
|
||||
constexpr float tableWidth = 520.0f;
|
||||
if (ImGui::BeginTable("ImportTable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable, ImVec2(tableWidth, 300)))
|
||||
{
|
||||
ImGui::TableSetupColumn("Filename", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, 120.0f);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (auto &[path, type] : pendingImports)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
std::string filename = GetFilenameFromPath(path);
|
||||
ImGui::TextWrapped("%s", filename.c_str());
|
||||
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
const char *currentLabel =
|
||||
type == AssetType::Image ? "Image" : type == AssetType::Audio ? "Audio"
|
||||
: type == AssetType::Prefab ? "Prefab"
|
||||
: "Unknown";
|
||||
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::BeginCombo(("##type_" + path).c_str(), currentLabel))
|
||||
{
|
||||
if (ImGui::Selectable("Image", type == AssetType::Image))
|
||||
type = AssetType::Image;
|
||||
if (ImGui::Selectable("Audio", type == AssetType::Audio))
|
||||
type = AssetType::Audio;
|
||||
if (ImGui::Selectable("Prefab", type == AssetType::Prefab))
|
||||
type = AssetType::Prefab;
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
float buttonWidth = 120.0f;
|
||||
float totalWidth = buttonWidth * 2 + ImGui::GetStyle().ItemSpacing.x;
|
||||
|
||||
ImGui::SetCursorPosX((tableWidth - totalWidth) * 0.5f); // center buttons
|
||||
if (ImGui::Button("Import", ImVec2(buttonWidth, 0)))
|
||||
{
|
||||
LoadingWindow loader;
|
||||
loader.Create("Importing...");
|
||||
|
||||
for (size_t i = 0; i < pendingImports.size(); ++i)
|
||||
{
|
||||
const auto &[path, type] = pendingImports[i];
|
||||
loader.Update("Importing", path, static_cast<float>(i + 1) / pendingImports.size());
|
||||
AssetManager::LoadAssetAsync(path, type);
|
||||
}
|
||||
|
||||
loader.Destroy();
|
||||
pendingImports.clear();
|
||||
showImportPopup = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel", ImVec2(buttonWidth, 0)))
|
||||
{
|
||||
pendingImports.clear();
|
||||
showImportPopup = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user