Added Prefab instatiation
This commit is contained in:
parent
dd29a6bfdf
commit
d645875322
28
imgui.ini
28
imgui.ini
@ -21,13 +21,13 @@ DockId=0x00000018,0
|
||||
|
||||
[Window][Scene Tree]
|
||||
Pos=0,19
|
||||
Size=342,579
|
||||
Size=347,579
|
||||
Collapsed=0
|
||||
DockId=0x0000000F,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=344,19
|
||||
Size=1207,659
|
||||
Pos=349,19
|
||||
Size=1202,659
|
||||
Collapsed=0
|
||||
DockId=0x00000017,0
|
||||
|
||||
@ -42,8 +42,8 @@ Collapsed=0
|
||||
DockId=0x00000016,0
|
||||
|
||||
[Window][Console]
|
||||
Pos=344,680
|
||||
Size=1206,273
|
||||
Pos=349,680
|
||||
Size=1201,273
|
||||
Collapsed=0
|
||||
DockId=0x00000013,0
|
||||
|
||||
@ -54,8 +54,8 @@ Collapsed=0
|
||||
DockId=0x00000017,1
|
||||
|
||||
[Window][Profiler]
|
||||
Pos=344,955
|
||||
Size=1206,222
|
||||
Pos=349,955
|
||||
Size=1201,222
|
||||
Collapsed=0
|
||||
DockId=0x00000014,0
|
||||
|
||||
@ -125,13 +125,13 @@ DockId=0x0000000D,0
|
||||
|
||||
[Window][Resources]
|
||||
Pos=0,600
|
||||
Size=342,577
|
||||
Size=347,577
|
||||
Collapsed=0
|
||||
DockId=0x00000010,0
|
||||
|
||||
[Window][Import Preview]
|
||||
Pos=351,22
|
||||
Size=550,1152
|
||||
Size=536,391
|
||||
Collapsed=0
|
||||
|
||||
[Table][0x96376740,2]
|
||||
@ -142,18 +142,18 @@ Column 1 Width=120
|
||||
[Docking][Data]
|
||||
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=0x00000001 Parent=0x00000005 SizeRef=347,701 Split=Y Selected=0x12EF0F59
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,637 Split=Y Selected=0x12EF0F59
|
||||
DockNode ID=0x0000000F Parent=0x00000003 SizeRef=342,579 HiddenTabBar=1 Selected=0x12EF0F59
|
||||
DockNode ID=0x00000010 Parent=0x00000003 SizeRef=342,577 HiddenTabBar=1 Selected=0x30401527
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,519 HiddenTabBar=1 Selected=0x36AF052B
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1576,701 Split=Y Selected=0xC450F867
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1571,701 Split=Y Selected=0xC450F867
|
||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,659 Split=X Selected=0xC450F867
|
||||
DockNode ID=0x00000017 Parent=0x00000007 SizeRef=1207,860 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
||||
DockNode ID=0x00000017 Parent=0x00000007 SizeRef=1202,860 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
||||
DockNode ID=0x00000018 Parent=0x00000007 SizeRef=367,860 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,497 Split=X Selected=0xEA83D666
|
||||
DockNode ID=0x00000015 Parent=0x00000008 SizeRef=1260,172 Split=X Selected=0xEA83D666
|
||||
DockNode ID=0x00000011 Parent=0x00000015 SizeRef=1206,168 Split=Y Selected=0x9B5D3198
|
||||
DockNode ID=0x00000015 Parent=0x00000008 SizeRef=1255,172 Split=X Selected=0xEA83D666
|
||||
DockNode ID=0x00000011 Parent=0x00000015 SizeRef=1201,168 Split=Y Selected=0x9B5D3198
|
||||
DockNode ID=0x00000013 Parent=0x00000011 SizeRef=1449,273 HiddenTabBar=1 Selected=0xEA83D666
|
||||
DockNode ID=0x00000014 Parent=0x00000011 SizeRef=1449,222 HiddenTabBar=1 Selected=0x9B5D3198
|
||||
DockNode ID=0x00000012 Parent=0x00000015 SizeRef=52,168 HiddenTabBar=1 Selected=0x56009A08
|
||||
|
@ -1,3 +1,3 @@
|
||||
[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\Engine.cpp -o src\build\Engine.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
|
||||
[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\core\utils\AssetManager.cpp -o src\build\core\utils\AssetManager.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\functions\Prefab.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
|
||||
[RUN] Executed app.exe successfully.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1220,6 +1220,48 @@ void Engine::Run()
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const ImGuiPayload *payload = ImGui::GetDragDropPayload();
|
||||
bool draggingPrefab = payload && payload->IsDataType("ASSET_PREFAB") && payload->DataSize == sizeof(uint64_t);
|
||||
|
||||
bool hoveringViewport = ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||
bool mouseReleased = ImGui::IsMouseReleased(ImGuiMouseButton_Left);
|
||||
|
||||
if (draggingPrefab && hoveringViewport && mouseReleased)
|
||||
{
|
||||
uint64_t uaid = *(const uint64_t *)payload->Data;
|
||||
|
||||
const auto *asset = AssetManager::GetAssetByID(uaid);
|
||||
if (!asset || asset->type != AssetType::Prefab)
|
||||
return;
|
||||
|
||||
auto prefabInfo = dynamic_cast<const PrefabAssetInfo *>(asset);
|
||||
if (!prefabInfo)
|
||||
{
|
||||
Logger::LogError("[AssetManager] Asset is not a PrefabAssetInfo");
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Object> newObj = prefabInfo->Instantiate();
|
||||
if (!newObj)
|
||||
{
|
||||
Logger::LogError("[Editor] Failed to instantiate prefab.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
ImVec2 screenMin = ImGui::GetWindowPos();
|
||||
ImVec2 localPos = ImVec2(mousePos.x - screenMin.x, mousePos.y - screenMin.y);
|
||||
|
||||
core::types::Vec2 worldPos = ScreenToWorld(core::types::Vec2(localPos), size, cameraPos, cameraZoom);
|
||||
newObj->SetWorldPosition(worldPos);
|
||||
|
||||
objects.push_back(newObj);
|
||||
|
||||
Logger::LogInfo("[Editor] Instantiated prefab at (%.2f, %.2f)", worldPos.x, worldPos.y);
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<Object> previewObj = nullptr;
|
||||
static uint64_t previewUAID = 0;
|
||||
|
||||
@ -1229,7 +1271,6 @@ void Engine::Run()
|
||||
bool mouseReleased = ImGui::IsMouseReleased(ImGuiMouseButton_Left);
|
||||
bool hoveringViewport = ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||
|
||||
// While dragging and hovering viewport
|
||||
if (draggingTexture && mouseHeld && hoveringViewport)
|
||||
{
|
||||
uint64_t uaid = *(const uint64_t *)payload->Data;
|
||||
|
@ -11,60 +11,62 @@
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
std::string Prefab::CreatePrefab(const std::shared_ptr<Object>& obj, const std::string& outputDir)
|
||||
{
|
||||
if (!obj)
|
||||
{
|
||||
Logger::LogError("[Prefab] Cannot create prefab from null object.");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string name = obj->GetName().empty() ? "Unnamed" : obj->GetName();
|
||||
for (char& c : name)
|
||||
{
|
||||
if (!std::isalnum(c) && c != '_' && c != '-' && c != ' ')
|
||||
c = '_';
|
||||
}
|
||||
// Clean filename
|
||||
std::string filename = obj->GetName().empty() ? "Unnamed" : obj->GetName();
|
||||
for (auto& ch : filename)
|
||||
if (ch == '/' || ch == '\\' || ch == ':' || ch == '*' || ch == '?' || ch == '\"' || ch == '<' || ch == '>' || ch == '|')
|
||||
ch = '_';
|
||||
|
||||
// Emit object YAML
|
||||
std::string path = outputDir + "/" + filename + ".cpfb";
|
||||
|
||||
// Serialize Object to string
|
||||
YAML::Emitter objectOut;
|
||||
objectOut.SetIndent(2);
|
||||
obj->Save(objectOut);
|
||||
|
||||
// Wrap metadata
|
||||
// Parse the object YAML string back into a real node
|
||||
YAML::Node objectNode;
|
||||
try {
|
||||
objectNode = YAML::Load(objectOut.c_str());
|
||||
} catch (const YAML::Exception& e) {
|
||||
Logger::LogError("[Prefab] Failed to parse object YAML for prefab: %s", e.what());
|
||||
return "";
|
||||
}
|
||||
|
||||
// Write the outer asset structure
|
||||
YAML::Emitter out;
|
||||
out.SetIndent(2);
|
||||
|
||||
std::string hash = HashString(objectOut.c_str());
|
||||
std::time_t now = std::time(nullptr);
|
||||
|
||||
out << YAML::BeginMap;
|
||||
|
||||
out << YAML::Key << "uaid" << YAML::Value << AssetManager::GenerateUAID();
|
||||
out << YAML::Key << "filename" << YAML::Value << name + ".cpfb";
|
||||
out << YAML::Key << "filename" << YAML::Value << filename + ".cpfb";
|
||||
out << YAML::Key << "filetype" << YAML::Value << "cpfb";
|
||||
out << YAML::Key << "type" << YAML::Value << "Prefab";
|
||||
out << YAML::Key << "prefabName" << YAML::Value << name;
|
||||
out << YAML::Key << "hash" << YAML::Value << hash;
|
||||
out << YAML::Key << "lastModified" << YAML::Value << now;
|
||||
out << YAML::Key << "loaded" << YAML::Value << true;
|
||||
out << YAML::Key << "prefabYAML" << YAML::Value << objectOut.c_str();
|
||||
out << YAML::Key << "prefabName" << YAML::Value << obj->GetName();
|
||||
out << YAML::Key << "hash" << YAML::Value << "";
|
||||
out << YAML::Key << "lastModified" << YAML::Value << GetFileLastWrite(path);
|
||||
out << YAML::Key << "prefabYAML" << YAML::Value << objectNode;
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
// Output file
|
||||
std::filesystem::create_directories(outputDir);
|
||||
std::string fullPath = outputDir + "/" + name + ".cpfb";
|
||||
|
||||
std::ofstream file(fullPath);
|
||||
std::ofstream file(path);
|
||||
if (file.is_open())
|
||||
{
|
||||
file << out.c_str();
|
||||
file.close();
|
||||
Logger::LogInfo("[Prefab] Saved prefab: %s", fullPath.c_str());
|
||||
return fullPath;
|
||||
Logger::LogInfo("[Prefab] Saved prefab: %s", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::LogError("[Prefab] Failed to save prefab: %s (%s)", fullPath.c_str(), std::strerror(errno));
|
||||
return "";
|
||||
Logger::LogError("[Prefab] Failed to write prefab file: %s (%s)", path.c_str(), std::strerror(errno));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <glm/glm.hpp>
|
||||
#include <imgui.h>
|
||||
|
||||
namespace core
|
||||
{
|
||||
@ -20,6 +21,7 @@ namespace core
|
||||
Vec2(float v) : x(v), y(v) {}
|
||||
Vec2(const glm::vec2 &v) : x(v.x), y(v.y) {}
|
||||
Vec2(const Vec2i &v);
|
||||
Vec2(const ImVec2 &v) : x(v.x), y(v.y) {}
|
||||
|
||||
operator glm::vec2() const { return {x, y}; }
|
||||
|
||||
@ -30,10 +32,30 @@ namespace core
|
||||
|
||||
Vec2 operator*(const Vec2 &rhs) const { return {x * rhs.x, y * rhs.y}; }
|
||||
|
||||
Vec2 &operator+=(const Vec2 &rhs) { x += rhs.x; y += rhs.y; return *this; }
|
||||
Vec2 &operator-=(const Vec2 &rhs) { x -= rhs.x; y -= rhs.y; return *this; }
|
||||
Vec2 &operator*=(float scalar) { x *= scalar; y *= scalar; return *this; }
|
||||
Vec2 &operator/=(float scalar) { x /= scalar; y /= scalar; return *this; }
|
||||
Vec2 &operator+=(const Vec2 &rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator-=(const Vec2 &rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator*=(float scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator/=(float scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2 operator-() const { return {-x, -y}; }
|
||||
|
||||
@ -99,10 +121,30 @@ namespace core
|
||||
|
||||
Vec2 operator*(const Vec2 &rhs) const { return Vec2(x * rhs.x, y * rhs.y); }
|
||||
|
||||
Vec2i &operator+=(const Vec2i &rhs) { x += rhs.x; y += rhs.y; return *this; }
|
||||
Vec2i &operator-=(const Vec2i &rhs) { x -= rhs.x; y -= rhs.y; return *this; }
|
||||
Vec2i &operator*=(int scalar) { x *= scalar; y *= scalar; return *this; }
|
||||
Vec2i &operator/=(int scalar) { x /= scalar; y /= scalar; return *this; }
|
||||
Vec2i &operator+=(const Vec2i &rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2i &operator-=(const Vec2i &rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2i &operator*=(int scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
return *this;
|
||||
}
|
||||
Vec2i &operator/=(int scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec2i &rhs) const { return x == rhs.x && y == rhs.y; }
|
||||
bool operator!=(const Vec2i &rhs) const { return !(*this == rhs); }
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include <stb_image.h>
|
||||
#include "../../Entitys/Object.h"
|
||||
|
||||
|
||||
|
||||
std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> AssetManager::s_Assets;
|
||||
std::unordered_map<std::string, uint64_t> AssetManager::s_PathToUAID;
|
||||
uint64_t AssetManager::s_NextUAID = 1;
|
||||
@ -169,77 +167,9 @@ 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");
|
||||
|
||||
}
|
||||
|
||||
uint64_t AssetManager::GenerateUAID()
|
||||
@ -262,6 +192,8 @@ void AssetManager::LoadAssetAsync(const std::string &path, AssetType type)
|
||||
asset = std::make_shared<ImageAssetInfo>();
|
||||
else if (type == AssetType::Audio)
|
||||
asset = std::make_shared<AudioAssetInfo>();
|
||||
else if (type == AssetType::Prefab)
|
||||
asset = std::make_shared<PrefabAssetInfo>();
|
||||
else
|
||||
{
|
||||
Logger::LogWarning("[AssetManager] Unknown Asset Type: '%d'", static_cast<int>(type));
|
||||
@ -282,7 +214,6 @@ void AssetManager::LoadAssetAsync(const std::string &path, AssetType type)
|
||||
LoadAudioInternal(path, uaid);
|
||||
else if (type == AssetType::Prefab)
|
||||
LoadPrefabInternal(path, uaid);
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::LoadImageInternal(const std::string &path, uint64_t uaid)
|
||||
@ -342,9 +273,6 @@ 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);
|
||||
@ -374,13 +302,9 @@ 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)
|
||||
if (auto it = s_Assets.find(uaid); it != s_Assets.end() && it->second->loaded)
|
||||
return;
|
||||
|
||||
if (!FileExists(path))
|
||||
@ -389,40 +313,55 @@ void AssetManager::LoadPrefabInternal(const std::string& path, uint64_t uaid)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string yamlContent;
|
||||
if (!ReadTextFile(path, yamlContent))
|
||||
std::string fileContent;
|
||||
if (!ReadTextFile(path, fileContent))
|
||||
{
|
||||
Logger::LogError("[AssetManager] Failed to read prefab file: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
YAML::Node root;
|
||||
try
|
||||
{
|
||||
root = YAML::Load(fileContent);
|
||||
}
|
||||
catch (const YAML::Exception &e)
|
||||
{
|
||||
Logger::LogError("[AssetManager] YAML parse error in %s: %s", path.c_str(), e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
YAML::Node inner = root["prefabYAML"];
|
||||
if (!inner || !inner.IsMap())
|
||||
{
|
||||
Logger::LogError("[AssetManager] Missing or invalid 'prefabYAML' in: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prefabName = root["prefabName"] ? root["prefabName"].as<std::string>() : "Unnamed Prefab";
|
||||
|
||||
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->prefabYAML = inner;
|
||||
prefab->prefabName = prefabName;
|
||||
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;
|
||||
}
|
||||
// Create and load root object
|
||||
prefab->prefabRoot = std::make_shared<Object>(prefabName);
|
||||
prefab->prefabRoot->Load(inner);
|
||||
|
||||
// Register asset
|
||||
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);
|
||||
@ -490,15 +429,12 @@ void AssetManager::Load(const YAML::Node &node)
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
|
||||
LoadingWindow loadingUI;
|
||||
loadingUI.Create("Loading Assets");
|
||||
|
||||
const size_t total = node.size();
|
||||
size_t index = 0;
|
||||
|
||||
|
||||
|
||||
for (const auto &item : node)
|
||||
{
|
||||
|
||||
@ -539,7 +475,6 @@ void AssetManager::Load(const YAML::Node &node)
|
||||
LoadAudioInternal(path, uaid);
|
||||
|
||||
++index;
|
||||
|
||||
}
|
||||
loadingUI.Destroy();
|
||||
}
|
||||
@ -564,3 +499,99 @@ void ImageAssetInfo::Load(const YAML::Node &node)
|
||||
|
||||
void AudioAssetInfo::Save(YAML::Emitter &out) const {}
|
||||
void AudioAssetInfo::Load(const YAML::Node &node) {}
|
||||
|
||||
|
||||
PrefabAssetInfo::PrefabAssetInfo()
|
||||
{
|
||||
type = AssetType::Prefab;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PrefabAssetInfo::Save(YAML::Emitter &out) const
|
||||
{
|
||||
|
||||
out << YAML::Key << "uaid" << YAML::Value << uaid;
|
||||
out << YAML::Key << "filename" << YAML::Value << filename;
|
||||
out << YAML::Key << "filetype" << YAML::Value << filetype;
|
||||
out << YAML::Key << "type" << YAML::Value << "Prefab";
|
||||
out << YAML::Key << "prefabName" << YAML::Value << prefabName;
|
||||
out << YAML::Key << "hash" << YAML::Value << hash;
|
||||
out << YAML::Key << "lastModified" << YAML::Value << lastModified;
|
||||
|
||||
out << YAML::Key << "prefabYAML";
|
||||
if (prefabRoot)
|
||||
{
|
||||
YAML::Emitter innerOut;
|
||||
innerOut.SetIndent(2);
|
||||
prefabRoot->Save(innerOut);
|
||||
|
||||
YAML::Node parsedInner;
|
||||
try
|
||||
{
|
||||
parsedInner = YAML::Load(innerOut.c_str());
|
||||
}
|
||||
catch (const YAML::Exception &e)
|
||||
{
|
||||
Logger::LogError("[PrefabAssetInfo] Failed to parse prefabRoot YAML for saving: %s", e.what());
|
||||
}
|
||||
|
||||
out << parsedInner;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << prefabYAML;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PrefabAssetInfo::Load(const YAML::Node &node)
|
||||
{
|
||||
uaid = node["uaid"] ? node["uaid"].as<uint64_t>() : 0;
|
||||
filename = node["filename"] ? node["filename"].as<std::string>() : "unknown.cpfb";
|
||||
filetype = node["filetype"] ? node["filetype"].as<std::string>() : "cpfb";
|
||||
type = AssetType::Prefab;
|
||||
prefabName = node["prefabName"] ? node["prefabName"].as<std::string>() : "Unnamed Prefab";
|
||||
hash = node["hash"] ? node["hash"].as<std::string>() : "";
|
||||
lastModified = node["lastModified"] ? node["lastModified"].as<uint64_t>() : 0;
|
||||
|
||||
if (!node["prefabYAML"] || !node["prefabYAML"].IsMap())
|
||||
{
|
||||
Logger::LogError("[PrefabAssetInfo] Missing or invalid 'prefabYAML' node in prefab file.");
|
||||
prefabYAML = YAML::Node();
|
||||
prefabRoot = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
prefabYAML = node["prefabYAML"];
|
||||
ReloadFromYAML();
|
||||
}
|
||||
|
||||
void PrefabAssetInfo::ReloadFromYAML()
|
||||
{
|
||||
if (!prefabYAML || !prefabYAML.IsMap())
|
||||
{
|
||||
Logger::LogError("[PrefabAsset] Invalid or missing prefab YAML node.");
|
||||
prefabRoot = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
prefabRoot = std::make_shared<Object>(prefabName);
|
||||
prefabRoot->Load(prefabYAML);
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Object> PrefabAssetInfo::Instantiate() const
|
||||
{
|
||||
if (!prefabYAML || !prefabYAML.IsMap())
|
||||
{
|
||||
Logger::LogError("[PrefabAsset] Cannot instantiate: prefab YAML is invalid.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto newObj = std::make_shared<Object>(prefabName);
|
||||
newObj->Load(prefabYAML);
|
||||
return newObj;
|
||||
}
|
||||
|
||||
|
@ -11,13 +11,46 @@
|
||||
|
||||
class Object;
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <string_view>
|
||||
|
||||
#define ASSET_TYPE_LIST \
|
||||
X(Image) \
|
||||
X(Audio) \
|
||||
X(Prefab) \
|
||||
X(Unknown)
|
||||
|
||||
enum class AssetType {
|
||||
Image,
|
||||
Audio,
|
||||
Prefab,
|
||||
Unknown
|
||||
#define X(name) name,
|
||||
ASSET_TYPE_LIST
|
||||
#undef X
|
||||
};
|
||||
|
||||
inline const char* AssetTypeToString(AssetType type) {
|
||||
switch (type) {
|
||||
#define X(name) case AssetType::name: return #name;
|
||||
ASSET_TYPE_LIST
|
||||
#undef X
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
inline AssetType StringToAssetType(const std::string_view str) {
|
||||
static const std::unordered_map<std::string_view, AssetType> map = {
|
||||
#define X(name) {#name, AssetType::name},
|
||||
ASSET_TYPE_LIST
|
||||
#undef X
|
||||
};
|
||||
|
||||
auto it = map.find(str);
|
||||
return it != map.end() ? it->second : AssetType::Unknown;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct AssetInfo
|
||||
{
|
||||
@ -63,21 +96,23 @@ struct AudioAssetInfo : public AssetInfo
|
||||
|
||||
struct PrefabAssetInfo : public AssetInfo
|
||||
{
|
||||
std::string prefabYAML;
|
||||
YAML::Node prefabYAML;
|
||||
std::shared_ptr<Object> prefabRoot = nullptr;
|
||||
|
||||
std::string prefabName = "Unnamed Prefab";
|
||||
|
||||
|
||||
PrefabAssetInfo();
|
||||
std::shared_ptr<Object> Instantiate() const;
|
||||
|
||||
void Save(YAML::Emitter& out) const override;
|
||||
void Load(const YAML::Node& node) override;
|
||||
|
||||
void ReloadFromYAML(); // reparses prefabYAML into prefabRoot
|
||||
void ReloadFromYAML();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const char* MiniaudioResultToString(ma_result result);
|
||||
|
||||
|
||||
|
@ -156,6 +156,25 @@ void ShowAssetBrowser()
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
else if (asset->type == AssetType::Prefab)
|
||||
{
|
||||
const auto *prefab = dynamic_cast<const PrefabAssetInfo *>(asset);
|
||||
|
||||
if (ImGui::Button(prefab->prefabName.empty() ? "##Prefab" : ("##" + prefab->prefabName).c_str(), ImVec2(thumbnailSize, thumbnailSize)))
|
||||
{
|
||||
}
|
||||
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + thumbnailSize);
|
||||
ImGui::TextWrapped("%s", prefab->prefabName.empty() ? "Prefab" : prefab->prefabName.c_str());
|
||||
ImGui::PopTextWrapPos();
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
||||
{
|
||||
ImGui::SetDragDropPayload("ASSET_PREFAB", &prefab->uaid, sizeof(uint64_t));
|
||||
ImGui::Text("%s", displayName.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PopID();
|
||||
|
Loading…
Reference in New Issue
Block a user