fix the child position incorrect while parenting node; add camera focus func; treat icons to the asset and using AssetsManager::GetAsset to load it

This commit is contained in:
2026-02-17 21:38:43 +08:00
parent 2bbe332532
commit 99bbf1eb5a
29 changed files with 414 additions and 254 deletions

View File

@ -177,6 +177,7 @@ namespace Prism
// OpenScene("assets/scenes/FPSDemo.scene"); // OpenScene("assets/scenes/FPSDemo.scene");
NewScene(); NewScene();
m_CurrentScene = m_RuntimeScene;
AssetEditorPanel::RegisterDefaultEditors(); AssetEditorPanel::RegisterDefaultEditors();
FileSystem::StartWatching(); FileSystem::StartWatching();
@ -804,11 +805,12 @@ namespace Prism
bool snap = Input::IsKeyPressed(Key::LEFT_CONTROL); bool snap = Input::IsKeyPressed(Key::LEFT_CONTROL);
TransformComponent& entityTransform = selection.Entity.Transform(); TransformComponent& entityTransform = selection.Entity.Transform();
// glm::mat4 transform = entityTransform.GetTransform();
glm::mat4 transform = m_CurrentScene->GetTransformRelativeToParent(selection.Entity);
float snapValue = GetSnapValue(); float snapValue = GetSnapValue();
float snapValues[3] = { snapValue, snapValue, snapValue }; float snapValues[3] = { snapValue, snapValue, snapValue };
if (m_SelectionMode == SelectionMode::Entity) if (m_SelectionMode == SelectionMode::Entity)
{ {
glm::mat4 transform = entityTransform.GetTransform();
ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()), ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()),
glm::value_ptr(m_EditorCamera.GetProjectionMatrix()), glm::value_ptr(m_EditorCamera.GetProjectionMatrix()),
(ImGuizmo::OPERATION)m_GizmoType, (ImGuizmo::OPERATION)m_GizmoType,
@ -822,16 +824,27 @@ namespace Prism
glm::vec3 translation, rotation, scale; glm::vec3 translation, rotation, scale;
Math::DecomposeTransform(transform, translation,rotation,scale); Math::DecomposeTransform(transform, translation,rotation,scale);
entityTransform.Translation = translation; if (Entity parent = m_CurrentScene->FindEntityByUUID(selection.Entity.GetParentUUID()))
{
glm::vec3 parentTranslation, parentRotation, parentScale;
Math::DecomposeTransform(m_CurrentScene->GetTransformRelativeToParent(parent), parentTranslation, parentRotation, parentScale);
glm::vec3 deltaRotation = rotation - entityTransform.Rotation; glm::vec3 deltaRotation = (rotation - parentRotation) - entityTransform.Rotation;
entityTransform.Translation = translation - parentTranslation;
entityTransform.Rotation += deltaRotation; entityTransform.Rotation += deltaRotation;
entityTransform.Scale = scale; entityTransform.Scale = scale;
} }
else
{
glm::vec3 deltaRotation = rotation - entityTransform.Rotation;
entityTransform.Translation = translation;
entityTransform.Rotation += deltaRotation;
entityTransform.Scale = scale;
}
}
}else }else
{ {
glm::mat4 transformBase = entityTransform.GetTransform() * selection.Mesh->Transform; glm::mat4 transformBase = transform * selection.Mesh->Transform;
ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()), ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()),
glm::value_ptr(m_EditorCamera.GetProjectionMatrix()), glm::value_ptr(m_EditorCamera.GetProjectionMatrix()),
(ImGuizmo::OPERATION)m_GizmoType, (ImGuizmo::OPERATION)m_GizmoType,
@ -918,6 +931,15 @@ namespace Prism
case KeyCode::R: case KeyCode::R:
m_GizmoType = ImGuizmo::OPERATION::SCALE; m_GizmoType = ImGuizmo::OPERATION::SCALE;
break; break;
case KeyCode::F:
{
if (m_SelectionContext.size() == 0)
break;
Entity selectedEntity = m_SelectionContext[0].Entity;
m_EditorCamera.Focus(selectedEntity.Transform().Translation);
break;
}
} }
} }
@ -1068,6 +1090,7 @@ namespace Prism
m_SelectionContext.push_back(selection); m_SelectionContext.push_back(selection);
m_EditorScene->SetSelectedEntity(entity); m_EditorScene->SetSelectedEntity(entity);
m_CurrentScene = m_EditorScene;
} }
void EditorLayer::UpdateWindowTitle(const std::string &sceneName) void EditorLayer::UpdateWindowTitle(const std::string &sceneName)
@ -1108,9 +1131,9 @@ namespace Prism
m_EditorScene->SetSelectedEntity(selectionContext.Entity); m_EditorScene->SetSelectedEntity(selectionContext.Entity);
} }
void EditorLayer::OnEntityDeleted(Entity e) void EditorLayer::OnEntityDeleted(const Entity e)
{ {
if (m_SelectionContext[0].Entity == e) if (m_SelectionContext.size() > 0 && m_SelectionContext[0].Entity == e)
{ {
m_SelectionContext.clear(); m_SelectionContext.clear();
m_EditorScene->SetSelectedEntity({}); m_EditorScene->SetSelectedEntity({});
@ -1164,6 +1187,7 @@ namespace Prism
m_EditorScene->SetSelectedEntity({}); m_EditorScene->SetSelectedEntity({});
m_SelectionContext.clear(); m_SelectionContext.clear();
m_CurrentScene = m_EditorScene;
} }
void EditorLayer::SaveScene() void EditorLayer::SaveScene()
@ -1213,6 +1237,7 @@ namespace Prism
m_RuntimeScene->OnRuntimeStart(); m_RuntimeScene->OnRuntimeStart();
m_SceneHierarchyPanel->SetContext(m_RuntimeScene); m_SceneHierarchyPanel->SetContext(m_RuntimeScene);
m_CurrentScene = m_RuntimeScene;
} }
void EditorLayer::OnSceneStop() void EditorLayer::OnSceneStop()
@ -1226,6 +1251,7 @@ namespace Prism
m_SelectionContext.clear(); m_SelectionContext.clear();
ScriptEngine::SetSceneContext(m_EditorScene); ScriptEngine::SetSceneContext(m_EditorScene);
m_SceneHierarchyPanel->SetContext(m_EditorScene); m_SceneHierarchyPanel->SetContext(m_EditorScene);
m_CurrentScene = m_EditorScene;
} }
float EditorLayer::GetSnapValue() const float EditorLayer::GetSnapValue() const

View File

@ -61,7 +61,7 @@ namespace Prism
Scope<AssetsManagerPanel> m_AssetManagerPanel; Scope<AssetsManagerPanel> m_AssetManagerPanel;
Scope<ObjectsPanel> m_ObjectsPanel; Scope<ObjectsPanel> m_ObjectsPanel;
Ref<Scene> m_ActiveScene; Ref<Scene> m_CurrentScene;
Ref<Scene> m_RuntimeScene, m_EditorScene; Ref<Scene> m_RuntimeScene, m_EditorScene;
std::string m_SceneFilePath; std::string m_SceneFilePath;

View File

@ -48,7 +48,7 @@ void main()
vec3 mappedColor = (mappedLuminance / luminance) * color* u_Exposure; vec3 mappedColor = (mappedLuminance / luminance) * color* u_Exposure;
// Gamma correction. // Gamma correction.
o_Color = vec4(color, 1.0); o_Color = vec4(mappedColor, 1.0);
#else #else
const float gamma = 2.2; const float gamma = 2.2;
vec3 hdrColor = texture(u_SceneTexture, v_TexCoord).rgb; vec3 hdrColor = texture(u_SceneTexture, v_TexCoord).rgb;

View File

@ -50,7 +50,7 @@ namespace Prism
public Vec3 Size { get; protected set; } public Vec3 Size { get; protected set; }
public Vec3 Offset { get; protected set; } public Vec3 Offset { get; protected set; }
private BoxCollider(ulong entityID, bool isTrigger, Vec3 size, Vec3 offset) internal BoxCollider(ulong entityID, bool isTrigger, Vec3 size, Vec3 offset)
{ {
EntityID = entityID; EntityID = entityID;
Size = size; Size = size;
@ -63,7 +63,7 @@ namespace Prism
{ {
public float Radius { get; protected set; } public float Radius { get; protected set; }
private SphereCollider(ulong entityID, bool isTrigger, float radius) internal SphereCollider(ulong entityID, bool isTrigger, float radius)
{ {
EntityID = entityID; EntityID = entityID;
Radius = radius; Radius = radius;
@ -76,7 +76,7 @@ namespace Prism
public float Radius { get; protected set; } public float Radius { get; protected set; }
public float Height { get; protected set; } public float Height { get; protected set; }
private CapsuleCollider(ulong entityID, bool isTrigger, float radius, float height) internal CapsuleCollider(ulong entityID, bool isTrigger, float radius, float height)
{ {
EntityID = entityID; EntityID = entityID;
Radius = radius; Radius = radius;
@ -89,7 +89,7 @@ namespace Prism
{ {
public Mesh Mesh { get; protected set; } public Mesh Mesh { get; protected set; }
private MeshCollider(ulong entityID, bool isTrigger, IntPtr filepath) internal MeshCollider(ulong entityID, bool isTrigger, IntPtr filepath)
{ {
EntityID = entityID; EntityID = entityID;
Mesh = new Mesh(filepath); Mesh = new Mesh(filepath);

View File

@ -12,7 +12,7 @@ namespace Prism
{ {
enum class AssetType enum class AssetType
{ {
Scene, Mesh, Texture, EnvMap, Audio, Script, PhysicsMat, Directory, Other Scene = 0, Mesh, Texture, EnvMap, Audio, Script, PhysicsMat, Directory, Other, None
}; };
using AssetHandle = UUID; using AssetHandle = UUID;
@ -21,7 +21,7 @@ namespace Prism
{ {
public: public:
AssetHandle Handle; AssetHandle Handle;
AssetType Type; AssetType Type = AssetType::None;
std::string FilePath; std::string FilePath;
std::string FileName; std::string FileName;
@ -56,7 +56,10 @@ namespace Prism
public: public:
std::vector<AssetHandle> ChildDirectories; std::vector<AssetHandle> ChildDirectories;
Directory() = default; Directory()
{
Type = AssetType::Directory;
}
}; };
} }

View File

@ -71,8 +71,9 @@ namespace Prism
const std::string extension = Utils::GetExtension(filepath); const std::string extension = Utils::GetExtension(filepath);
asset->FilePath = filepath; asset->FilePath = filepath;
asset->Type = type;
std::replace(asset->FilePath.begin(), asset->FilePath.end(), '\\', '/'); std::replace(asset->FilePath.begin(), asset->FilePath.end(), '\\', '/');
const bool hasMeta = FileSystem::Exists(asset->FilePath + ".meta"); const bool hasMeta = FileSystem::Exists(asset->FilePath + ".meta");
@ -82,16 +83,12 @@ namespace Prism
} }
else else
{ {
if (filepath == "assets")
asset->Handle = 0;
else
asset->Handle = AssetHandle(); asset->Handle = AssetHandle();
asset->FileName = Utils::RemoveExtension(Utils::GetFilename(filepath));
asset->Extension = Utils::GetExtension(filepath);
asset->Type = type;
} }
// TODO: file or directory Type to fix
asset->Extension = extension;
asset->FileName = Utils::RemoveExtension(Utils::GetFilename(filepath));
asset->ParentDirectory = parentHandle; asset->ParentDirectory = parentHandle;
asset->IsDataLoaded = false; asset->IsDataLoaded = false;
@ -174,10 +171,15 @@ namespace Prism
} }
asset->Handle = data["Asset"].as<uint64_t>(); asset->Handle = data["Asset"].as<uint64_t>();
asset->FileName = data["FileName"].as<std::string>();
asset->FilePath = data["FilePath"].as<std::string>(); asset->FilePath = data["FilePath"].as<std::string>();
asset->Extension = data["Extension"].as<std::string>();
asset->Type = (AssetType)data["Type"].as<int>(); asset->Type = (AssetType)data["Type"].as<int>();
if (asset->FileName == "assets" && asset->Handle == 0)
{
asset->Handle = AssetHandle();
CreateMetaFile(asset);
}
} }
void AssetSerializer::CreateMetaFile(const Ref<Asset>& asset) void AssetSerializer::CreateMetaFile(const Ref<Asset>& asset)
@ -185,10 +187,7 @@ namespace Prism
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginMap; out << YAML::BeginMap;
out << YAML::Key << "Asset" << YAML::Value << asset->Handle; out << YAML::Key << "Asset" << YAML::Value << asset->Handle;
out << YAML::Key << "FileName" << YAML::Value << asset->FileName;
out << YAML::Key << "FilePath" << YAML::Value << asset->FilePath; out << YAML::Key << "FilePath" << YAML::Value << asset->FilePath;
out << YAML::Key << "Extension" << YAML::Value << asset->Extension;
out << YAML::Key << "Directory" << YAML::Value << asset->ParentDirectory;
out << YAML::Key << "Type" << YAML::Value << (int)asset->Type; out << YAML::Key << "Type" << YAML::Value << (int)asset->Type;
out << YAML::EndMap; out << YAML::EndMap;

View File

@ -33,20 +33,6 @@ namespace Prism
s_Types["cs"] = AssetType::Script; s_Types["cs"] = AssetType::Script;
} }
size_t AssetTypes::GetAssetTypeID(const std::string& extension)
{
if (extension.empty())
return 0;
for (const auto& kv : s_Types)
{
if (kv.first == extension)
return std::hash<std::string>()(extension);
}
return -1;
}
AssetType AssetTypes::GetAssetTypeFromExtension(const std::string& extension) AssetType AssetTypes::GetAssetTypeFromExtension(const std::string& extension)
{ {
return s_Types.find(extension) != s_Types.end() ? s_Types[extension] : AssetType::Other; return s_Types.find(extension) != s_Types.end() ? s_Types[extension] : AssetType::Other;
@ -121,7 +107,7 @@ namespace Prism
return false; return false;
} }
AssetHandle AssetsManager::GetAssetIDForFile(const std::string& filepath) AssetHandle AssetsManager::GetAssetHandleFromFilePath(const std::string& filepath)
{ {
for (auto&[id, asset] : s_LoadedAssets) for (auto&[id, asset] : s_LoadedAssets)
{ {
@ -134,7 +120,7 @@ namespace Prism
bool AssetsManager::IsAssetHandleValid(const AssetHandle& assetHandle) bool AssetsManager::IsAssetHandleValid(const AssetHandle& assetHandle)
{ {
return s_LoadedAssets.find(assetHandle) != s_LoadedAssets.end(); return assetHandle != 0 && s_LoadedAssets.find(assetHandle) != s_LoadedAssets.end();
} }
void AssetsManager::Rename(Ref<Asset>& asset, const std::string& newName) void AssetsManager::Rename(Ref<Asset>& asset, const std::string& newName)
@ -157,22 +143,38 @@ namespace Prism
} }
template <typename T> template <typename T>
Ref<T> AssetsManager::GetAsset(const AssetHandle assetHandle) Ref<T> AssetsManager::GetAsset(AssetHandle assetHandle, bool loadData)
{ {
PM_CORE_ASSERT(s_LoadedAssets.find(assetHandle) != s_LoadedAssets.end()); PM_CORE_ASSERT(s_LoadedAssets.find(assetHandle) != s_LoadedAssets.end());
Ref<Asset> asset = s_LoadedAssets[assetHandle]; Ref<Asset> asset = s_LoadedAssets[assetHandle];
if (!asset->IsDataLoaded) if (!asset->IsDataLoaded && loadData)
asset = AssetSerializer::LoadAssetData(asset); asset = AssetSerializer::LoadAssetData(asset);
return asset.As<T>(); return asset.As<T>();
} }
template PRISM_API Ref<Asset> AssetsManager::GetAsset(AssetHandle);
template PRISM_API Ref<Mesh> AssetsManager::GetAsset(AssetHandle); template PRISM_API Ref<Asset> AssetsManager::GetAsset(AssetHandle, bool);
template PRISM_API Ref<PhysicsMaterial> AssetsManager::GetAsset(AssetHandle); template PRISM_API Ref<Mesh> AssetsManager::GetAsset(AssetHandle, bool);
template PRISM_API Ref<Environment> AssetsManager::GetAsset(AssetHandle); template PRISM_API Ref<PhysicsMaterial> AssetsManager::GetAsset(AssetHandle, bool);
template PRISM_API Ref<Directory> AssetsManager::GetAsset(AssetHandle); template PRISM_API Ref<Environment> AssetsManager::GetAsset(AssetHandle, bool);
template PRISM_API Ref<Directory> AssetsManager::GetAsset(AssetHandle, bool);
template PRISM_API Ref<Texture2D> AssetsManager::GetAsset(AssetHandle, bool);
template <typename T>
Ref<T> AssetsManager::GetAsset(const std::string& filepath, const bool loadData)
{
return GetAsset<T>(GetAssetHandleFromFilePath(filepath), loadData);
}
template PRISM_API Ref<Asset> AssetsManager::GetAsset(const std::string&, bool);
template PRISM_API Ref<Mesh> AssetsManager::GetAsset(const std::string&, bool);
template PRISM_API Ref<PhysicsMaterial> AssetsManager::GetAsset(const std::string&, bool);
template PRISM_API Ref<Environment> AssetsManager::GetAsset(const std::string&, bool);
template PRISM_API Ref<Directory> AssetsManager::GetAsset(const std::string&, bool);
template PRISM_API Ref<Texture2D> AssetsManager::GetAsset(const std::string&, bool);
// temp // temp
Ref<PhysicsMaterial> AssetsManager::CreateAssetPhysicsMaterial(const std::string& filename, const AssetType type, const AssetHandle& directoryHandle, float v1, float v2, float v3) Ref<PhysicsMaterial> AssetsManager::CreateAssetPhysicsMaterial(const std::string& filename, const AssetType type, const AssetHandle& directoryHandle, float v1, float v2, float v3)
@ -205,7 +207,7 @@ namespace Prism
childList.erase(std::remove(childList.begin(), childList.end(), assetHandle), childList.end()); childList.erase(std::remove(childList.begin(), childList.end(), assetHandle), childList.end());
} }
for (auto child : asset.As<Directory>()->ChildDirectories) for (const auto child : asset.As<Directory>()->ChildDirectories)
RemoveAsset(child); RemoveAsset(child);
for (auto it = s_LoadedAssets.begin(); it != s_LoadedAssets.end(); ) for (auto it = s_LoadedAssets.begin(); it != s_LoadedAssets.end(); )
@ -306,51 +308,13 @@ namespace Prism
s_LoadedAssets[asset->Handle] = asset; s_LoadedAssets[asset->Handle] = asset;
} }
void AssetsManager::ConvertAsset(const std::string& assetPath, const std::string& conversionType)
{
// Create a filestream to write a blender python script for conversion of the asset
// The 'bpy.ops.export_scene.(asset-type-to-convert) function runs blender in background and exports the file'
std::string path = std::filesystem::temp_directory_path().string();
std::ofstream fileStream(path + "export.py");
// Importing the python modules required for the export to work out
fileStream << "import bpy\n";
fileStream << "import sys\n";
if (conversionType == "fbx")
fileStream << "bpy.ops.export_scene.fbx(filepath=r'" + path + "asset.fbx" + "', axis_forward='-Z', axis_up='Y')\n";
if (conversionType == "obj")
fileStream << "bpy.ops.export_scene.obj(filepath=r'" + path + "asset.obj" + "', axis_forward='-Z', axis_up='Y')\n";
fileStream.close();
// This section involves creating the command to export the .blend file to the required asset type
// The command goes something like this
// blender.exe path\to\files\cube.blend --background --python path\to\file\export.py
std::string blender_base_path = R"(D:\Application\Blender5.0.1\blender.exe)";
std::string p_asset_path = '"' + assetPath + '"';
std::string p_blender_path = '"' + blender_base_path + '"';
std::string p_script_path = '"' + path + "export.py" + '"';
// Creating the actual command that will execute
std::string convCommand = '"' + p_blender_path + " " + p_asset_path + " --background --python " + p_script_path + "" + '"';
// Just for debugging(it took me 1hr for this string literals n stuff! It better work!)
PM_CORE_INFO("{0}", convCommand);
// Fire the above created command
system(convCommand.c_str());
}
AssetHandle AssetsManager::ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle) AssetHandle AssetsManager::ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle)
{ {
Ref<Directory> dirInfo = AssetSerializer::LoadAssetInfo(directoryPath, parentHandle, AssetType::Directory).As<Directory>(); Ref<Directory> dirInfo = AssetSerializer::LoadAssetInfo(directoryPath, parentHandle, AssetType::Directory).As<Directory>();
s_LoadedAssets[dirInfo->Handle] = dirInfo; s_LoadedAssets[dirInfo->Handle] = dirInfo;
if (parentHandle != dirInfo->Handle && IsAssetHandleValid(parentHandle)) if (IsAssetHandleValid(parentHandle))
s_LoadedAssets[parentHandle].As<Directory>()->ChildDirectories.push_back(dirInfo->Handle); s_LoadedAssets[parentHandle].As<Directory>()->ChildDirectories.push_back(dirInfo->Handle);
for (const auto& entry : std::filesystem::directory_iterator(directoryPath)) for (const auto& entry : std::filesystem::directory_iterator(directoryPath))
@ -444,7 +408,7 @@ namespace Prism
{ {
const std::vector<std::string> parts = Utils::SplitString(filepath, "/\\"); const std::vector<std::string> parts = Utils::SplitString(filepath, "/\\");
const std::string& parentFolder = parts[parts.size() - 2]; const std::string& parentFolder = parts[parts.size() - 2];
Ref<Directory> assetsDirectory = GetAsset<Directory>(0); Ref<Directory> assetsDirectory = GetAsset<Directory>(GetAssetHandleFromFilePath("assets"));
return FindParentHandleInChildren(assetsDirectory, parentFolder); return FindParentHandleInChildren(assetsDirectory, parentFolder);
} }
} }

View File

@ -18,7 +18,6 @@ namespace Prism
{ {
public: public:
static void Init(); static void Init();
static size_t GetAssetTypeID(const std::string& extension);
static AssetType GetAssetTypeFromExtension(const std::string& extension); static AssetType GetAssetTypeFromExtension(const std::string& extension);
private: private:
@ -43,7 +42,7 @@ namespace Prism
static bool IsDirectory(const std::string& filepath); static bool IsDirectory(const std::string& filepath);
static AssetHandle GetAssetIDForFile(const std::string& filepath); static AssetHandle GetAssetHandleFromFilePath(const std::string& filepath);
static bool IsAssetHandleValid(const AssetHandle& assetHandle); static bool IsAssetHandleValid(const AssetHandle& assetHandle);
static void Rename(Ref<Asset>& asset, const std::string& newName); static void Rename(Ref<Asset>& asset, const std::string& newName);
@ -56,7 +55,10 @@ namespace Prism
static Ref<T> CreateAsset(const std::string& filename, AssetType type, AssetHandle directoryHandle, Args&&... args); static Ref<T> CreateAsset(const std::string& filename, AssetType type, AssetHandle directoryHandle, Args&&... args);
template<typename T> template<typename T>
static Ref<T> GetAsset(AssetHandle assetHandle); static Ref<T> GetAsset(AssetHandle assetHandle, bool loadData = true);
template<typename T>
static Ref<T> GetAsset(const std::string& filepath, bool loadData = true);
static bool IsAssetType(AssetHandle assetHandle, AssetType type); static bool IsAssetType(AssetHandle assetHandle, AssetType type);
@ -65,7 +67,6 @@ namespace Prism
private: private:
static void ImportAsset(const std::string& filepath, AssetHandle parentHandle); static void ImportAsset(const std::string& filepath, AssetHandle parentHandle);
static void ConvertAsset(const std::string& assetPath, const std::string& conversionType);
static AssetHandle ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle); static AssetHandle ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle);
static void ReloadAssets(); static void ReloadAssets();

View File

@ -260,7 +260,7 @@ namespace Prism::UI {
} }
template<typename T> template<typename T>
static bool PropertyAssetReference(const char* label, Ref<T>& object, AssetType supportedType) static bool PropertyAssetReference(const char* label, Ref<T>& object, const AssetType supportedType)
{ {
bool modified = false; bool modified = false;
@ -281,11 +281,9 @@ namespace Prism::UI {
if (ImGui::BeginDragDropTarget()) if (ImGui::BeginDragDropTarget())
{ {
auto data = ImGui::AcceptDragDropPayload("asset_payload"); if (const auto data = ImGui::AcceptDragDropPayload("asset_payload"))
if (data)
{ {
AssetHandle assetHandle = *(AssetHandle*)data->Data; const AssetHandle assetHandle = *(AssetHandle*)data->Data;
if (AssetsManager::IsAssetType(assetHandle, supportedType)) if (AssetsManager::IsAssetType(assetHandle, supportedType))
{ {
object = AssetsManager::GetAsset<T>(assetHandle); object = AssetsManager::GetAsset<T>(assetHandle);

View File

@ -19,7 +19,6 @@ namespace Prism
if (!m_IsOpen) if (!m_IsOpen)
return; return;
// NOTE(Peter): SetNextWindowSizeConstraints requires a max constraint that's above 0. For now we're just setting it to a large value
ImGui::SetNextWindowSizeConstraints(m_MinSize, m_MaxSize); ImGui::SetNextWindowSizeConstraints(m_MinSize, m_MaxSize);
ImGui::Begin(m_Title, &m_IsOpen, m_Flags); ImGui::Begin(m_Title, &m_IsOpen, m_Flags);
Render(); Render();
@ -46,7 +45,7 @@ namespace Prism
void AssetEditorPanel::RegisterDefaultEditors() void AssetEditorPanel::RegisterDefaultEditors()
{ {
RegisterEditor<TextureEditor>(AssetType::Texture); RegisterEditor<TextureViewer>(AssetType::Texture);
RegisterEditor<PhysicsMaterialEditor>(AssetType::PhysicsMat); RegisterEditor<PhysicsMaterialEditor>(AssetType::PhysicsMat);
} }
@ -65,7 +64,7 @@ namespace Prism
} }
s_Editors[asset->Type]->SetOpen(true); s_Editors[asset->Type]->SetOpen(true);
s_Editors[asset->Type]->SetAsset(asset); s_Editors[asset->Type]->SetAsset(AssetsManager::GetAsset<Asset>(asset->Handle));
} }
template <typename T> template <typename T>
@ -76,7 +75,7 @@ namespace Prism
s_Editors[type] = CreateScope<T>(); s_Editors[type] = CreateScope<T>();
} }
template PRISM_API void AssetEditorPanel::RegisterEditor<TextureEditor>(AssetType); template PRISM_API void AssetEditorPanel::RegisterEditor<TextureViewer>(AssetType);
template PRISM_API void AssetEditorPanel::RegisterEditor<PhysicsMaterialEditor>(AssetType); template PRISM_API void AssetEditorPanel::RegisterEditor<PhysicsMaterialEditor>(AssetType);
std::unordered_map<AssetType, Scope<AssetEditor>> AssetEditorPanel::s_Editors; std::unordered_map<AssetType, Scope<AssetEditor>> AssetEditorPanel::s_Editors;

View File

@ -20,27 +20,25 @@ namespace Prism
UpdateCurrentDirectory(m_CurrentDirHandle); UpdateCurrentDirectory(m_CurrentDirHandle);
}); });
m_FolderTex = Texture2D::Create("assets/editor/folder.png"); m_FileTex = AssetsManager::GetAsset<Texture2D>("assets/editor/file.png");
m_AssetIconMap[""] = AssetsManager::GetAsset<Texture2D>("assets/editor/folder.png");
m_AssetIconMap[-1] = Texture2D::Create("assets/editor/file.png"); m_AssetIconMap["hdr"] = AssetsManager::GetAsset<Texture2D>("assets/editor/file.png");
m_AssetIconMap[0] = m_FolderTex; m_AssetIconMap["fbx"] = AssetsManager::GetAsset<Texture2D>("assets/editor/fbx.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("hdr")] = Texture2D::Create("assets/editor/file.png"); m_AssetIconMap["obj"] = AssetsManager::GetAsset<Texture2D>("assets/editor/obj.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("fbx")] = Texture2D::Create("assets/editor/fbx.png"); m_AssetIconMap["wav"] = AssetsManager::GetAsset<Texture2D>("assets/editor/wav.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("obj")] = Texture2D::Create("assets/editor/obj.png"); m_AssetIconMap["cs"] = AssetsManager::GetAsset<Texture2D>("assets/editor/csc.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("wav")] = Texture2D::Create("assets/editor/wav.png"); m_AssetIconMap["png"] = AssetsManager::GetAsset<Texture2D>("assets/editor/png.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("cs")] = Texture2D::Create("assets/editor/csc.png"); m_AssetIconMap["blend"] = AssetsManager::GetAsset<Texture2D>("assets/editor/blend.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("png")] = Texture2D::Create("assets/editor/png.png");
m_AssetIconMap[AssetTypes::GetAssetTypeID("blend")] = Texture2D::Create("assets/editor/blend.png");
// TODO: get a logo for this project // TODO: get a logo for this project
m_AssetIconMap[AssetTypes::GetAssetTypeID("scene")] = Texture2D::Create("assets/editor/asset.png"); m_AssetIconMap["scene"] = Texture2D::Create("assets/editor/asset.png");
m_BackbtnTex = Texture2D::Create("assets/editor/btn_back.png"); m_BackbtnTex = AssetsManager::GetAsset<Texture2D>("assets/editor/btn_back.png");
m_FwrdbtnTex = Texture2D::Create("assets/editor/btn_fwrd.png"); m_FwrdbtnTex = AssetsManager::GetAsset<Texture2D>("assets/editor/btn_fwrd.png");
m_FolderRightTex = Texture2D::Create("assets/editor/folder_hierarchy.png"); m_FolderRightTex = AssetsManager::GetAsset<Texture2D>("assets/editor/folder_hierarchy.png");
m_SearchTex = Texture2D::Create("assets/editor/search.png"); m_SearchTex = AssetsManager::GetAsset<Texture2D>("assets/editor/search.png");
m_BaseDirectoryHandle = 0; m_BaseDirectoryHandle = AssetsManager::GetAssetHandleFromFilePath("assets");
m_BaseDirectory = AssetsManager::GetAsset<Directory>(m_BaseDirectoryHandle); m_BaseDirectory = AssetsManager::GetAsset<Directory>(m_BaseDirectoryHandle);
UpdateCurrentDirectory(m_BaseDirectoryHandle); UpdateCurrentDirectory(m_BaseDirectoryHandle);
@ -89,6 +87,7 @@ namespace Prism
{ {
m_SelectedAssets.Clear(); m_SelectedAssets.Clear();
m_RenamingSelected = false; m_RenamingSelected = false;
memset(m_InputBuffer, 0, MAX_INPUT_BUFFER_LENGTH);
} }
m_IsAnyItemHovered = false; m_IsAnyItemHovered = false;
@ -106,7 +105,7 @@ namespace Prism
if (created) if (created)
{ {
UpdateCurrentDirectory(m_CurrentDirHandle); UpdateCurrentDirectory(m_CurrentDirHandle);
const auto& createdDirectory = AssetsManager::GetAsset<Directory>(AssetsManager::GetAssetIDForFile(m_CurrentDirectory->FilePath + "/New Folder")); const auto& createdDirectory = AssetsManager::GetAsset<Directory>(AssetsManager::GetAssetHandleFromFilePath(m_CurrentDirectory->FilePath + "/New Folder"));
m_SelectedAssets.Select(createdDirectory->Handle); m_SelectedAssets.Select(createdDirectory->Handle);
memset(m_InputBuffer, 0, MAX_INPUT_BUFFER_LENGTH); memset(m_InputBuffer, 0, MAX_INPUT_BUFFER_LENGTH);
memcpy(m_InputBuffer, createdDirectory->FileName.c_str(), createdDirectory->FileName.size()); memcpy(m_InputBuffer, createdDirectory->FileName.c_str(), createdDirectory->FileName.size());
@ -158,16 +157,17 @@ namespace Prism
{ {
for (Ref<Asset>& asset : m_CurrentDirAssets) for (Ref<Asset>& asset : m_CurrentDirAssets)
{ {
if (m_SkipRenderingThisFrame)
{
m_SkipRenderingThisFrame = false;
break;
}
RenderAsset(asset); RenderAsset(asset);
ImGui::NextColumn(); ImGui::NextColumn();
} }
} }
if (m_UpdateDirectoryNextFrame)
{
UpdateCurrentDirectory(m_CurrentDirHandle);
m_UpdateDirectoryNextFrame = false;
}
if (m_IsDragging && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, 0.1f)) if (m_IsDragging && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, 0.1f))
{ {
m_IsDragging = false; m_IsDragging = false;
@ -217,15 +217,13 @@ namespace Prism
void AssetsManagerPanel::RenderAsset(Ref<Asset>& asset) void AssetsManagerPanel::RenderAsset(Ref<Asset>& asset)
{ {
// These caches are currently required for when we change directories // These caches are currently required for when we change directories
AssetHandle assetHandle = asset->Handle; const AssetHandle assetHandle = asset->Handle;
std::string filename = asset->FileName; const std::string filename = asset->FileName;
ImGui::PushID(&asset->Handle); ImGui::PushID(&asset->Handle);
ImGui::BeginGroup(); ImGui::BeginGroup();
size_t fileID = AssetTypes::GetAssetTypeID(asset->Extension); const RendererID iconRef = m_AssetIconMap.find(asset->Extension) != m_AssetIconMap.end() ? m_AssetIconMap[asset->Extension]->GetRendererID() : m_FileTex->GetRendererID();
fileID = m_AssetIconMap.find(fileID) != m_AssetIconMap.end() ? fileID : -1;
const RendererID iconRef = m_AssetIconMap[fileID]->GetRendererID();
if (m_SelectedAssets.IsSelected(assetHandle)) if (m_SelectedAssets.IsSelected(assetHandle))
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.25f, 0.25f, 0.75f)); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.25f, 0.25f, 0.75f));
@ -247,8 +245,8 @@ namespace Prism
if (asset->Type == AssetType::Directory) if (asset->Type == AssetType::Directory)
{ {
m_PrevDirHandle = m_CurrentDirHandle; m_PrevDirHandle = m_CurrentDirHandle;
UpdateCurrentDirectory(assetHandle); m_CurrentDirHandle = assetHandle;
m_SkipRenderingThisFrame = true; m_UpdateDirectoryNextFrame = true;
} }
else else
{ {
@ -317,8 +315,7 @@ namespace Prism
{ {
FileSystem::PrismDeleteFile(filepath + ".meta"); FileSystem::PrismDeleteFile(filepath + ".meta");
AssetsManager::RemoveAsset(assetHandle); AssetsManager::RemoveAsset(assetHandle);
m_SkipRenderingThisFrame = true; m_UpdateDirectoryNextFrame = true;
UpdateCurrentDirectory(m_CurrentDirHandle);
} }
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
@ -350,6 +347,31 @@ namespace Prism
void AssetsManagerPanel::HandleDragDrop(const RendererID icon, const Ref<Asset>& asset) void AssetsManagerPanel::HandleDragDrop(const RendererID icon, const Ref<Asset>& asset)
{ {
if (asset->Type == AssetType::Directory && m_IsDragging)
{
if (ImGui::BeginDragDropTarget())
{
auto payload = ImGui::AcceptDragDropPayload("asset_payload");
if (payload)
{
int count = payload->DataSize / sizeof(AssetHandle);
for (int i = 0; i < count; i++)
{
AssetHandle handle = *(((AssetHandle*)payload->Data) + i);
Ref<Asset> droppedAsset = AssetsManager::GetAsset<Asset>(handle, false);
bool result = FileSystem::PrismMoveFile(droppedAsset->FilePath, asset->FilePath);
if (result)
droppedAsset->ParentDirectory = asset->Handle;
}
m_UpdateDirectoryNextFrame = true;
}
}
}
if (!m_SelectedAssets.IsSelected(asset->Handle) || m_IsDragging) if (!m_SelectedAssets.IsSelected(asset->Handle) || m_IsDragging)
return; return;
@ -393,7 +415,7 @@ namespace Prism
ImGui::PushItemWidth(200); ImGui::PushItemWidth(200);
char* buf = m_InputBuffer; char* buf = m_InputBuffer;
if (m_RenamingSelected) if (m_RenamingSelected)
buf = '\0'; *buf = '\0';
if (ImGui::InputTextWithHint("##asset_panel_search", "Search...", buf, MAX_INPUT_BUFFER_LENGTH)) if (ImGui::InputTextWithHint("##asset_panel_search", "Search...", buf, MAX_INPUT_BUFFER_LENGTH))
{ {
@ -424,7 +446,6 @@ namespace Prism
currentHandle = dirInfo->ParentDirectory; currentHandle = dirInfo->ParentDirectory;
} }
m_BreadCrumbData.push_back(m_BaseDirectory);
std::reverse(m_BreadCrumbData.begin(), m_BreadCrumbData.end()); std::reverse(m_BreadCrumbData.begin(), m_BreadCrumbData.end());
m_UpdateBreadCrumbs = false; m_UpdateBreadCrumbs = false;
@ -475,8 +496,7 @@ namespace Prism
AssetsManager::Rename(asset, m_InputBuffer); AssetsManager::Rename(asset, m_InputBuffer);
m_RenamingSelected = false; m_RenamingSelected = false;
m_SelectedAssets.Clear(); m_SelectedAssets.Clear();
m_SkipRenderingThisFrame = true; m_UpdateDirectoryNextFrame = true;
UpdateCurrentDirectory(m_CurrentDirHandle);
} }
} }
} }
@ -484,7 +504,6 @@ namespace Prism
void AssetsManagerPanel::UpdateCurrentDirectory(AssetHandle directoryHandle) void AssetsManagerPanel::UpdateCurrentDirectory(AssetHandle directoryHandle)
{ {
if (m_CurrentDirHandle != directoryHandle)
m_UpdateBreadCrumbs = true; m_UpdateBreadCrumbs = true;
m_CurrentDirAssets.clear(); m_CurrentDirAssets.clear();

View File

@ -82,7 +82,7 @@ namespace Prism
void UpdateCurrentDirectory(AssetHandle directoryHandle); void UpdateCurrentDirectory(AssetHandle directoryHandle);
private: private:
Ref<Texture2D> m_FolderTex; Ref<Texture2D> m_FileTex;
Ref<Texture2D> m_BackbtnTex; Ref<Texture2D> m_BackbtnTex;
Ref<Texture2D> m_FwrdbtnTex; Ref<Texture2D> m_FwrdbtnTex;
Ref<Texture2D> m_FolderRightTex; Ref<Texture2D> m_FolderRightTex;
@ -93,7 +93,7 @@ namespace Prism
bool m_IsDragging = false; bool m_IsDragging = false;
bool m_UpdateBreadCrumbs = true; bool m_UpdateBreadCrumbs = true;
bool m_IsAnyItemHovered = false; bool m_IsAnyItemHovered = false;
bool m_SkipRenderingThisFrame = false; bool m_UpdateDirectoryNextFrame = false;
char m_InputBuffer[MAX_INPUT_BUFFER_LENGTH]; char m_InputBuffer[MAX_INPUT_BUFFER_LENGTH];
@ -112,7 +112,7 @@ namespace Prism
bool m_RenamingSelected = false; bool m_RenamingSelected = false;
std::map<size_t, Ref<Texture2D>> m_AssetIconMap; std::map<std::string, Ref<Texture2D>> m_AssetIconMap;
}; };
} }

View File

@ -25,14 +25,14 @@ namespace Prism
// MaterialEditor // MaterialEditor
TextureEditor::TextureEditor() TextureViewer::TextureViewer()
: AssetEditor("Edit Texture") : AssetEditor("Edit Texture")
{ {
SetMinSize(200, 600); SetMinSize(200, 600);
SetMaxSize(500, 1000); SetMaxSize(500, 1000);
} }
void TextureEditor::Render() void TextureViewer::Render()
{ {
if (!m_Asset) if (!m_Asset)
SetOpen(false); SetOpen(false);

View File

@ -24,10 +24,10 @@ namespace Prism
Ref<PhysicsMaterial> m_Asset; Ref<PhysicsMaterial> m_Asset;
}; };
class TextureEditor : public AssetEditor class TextureViewer : public AssetEditor
{ {
public: public:
TextureEditor(); TextureViewer();
virtual void SetAsset(const Ref<Asset>& asset) override { m_Asset = static_cast<Ref<Texture>>(asset); } virtual void SetAsset(const Ref<Asset>& asset) override { m_Asset = static_cast<Ref<Texture>>(asset); }

View File

@ -33,8 +33,15 @@ namespace Prism
UpdateCameraView(); UpdateCameraView();
} }
void EditorCamera::Focus() void EditorCamera::Focus(const glm::vec3& focusPoint)
{ {
m_FocalPoint = focusPoint;
if (m_Distance > m_MinFocusDistance)
{
const float distance = m_Distance - m_MinFocusDistance;
MouseZoom(distance / ZoomSpeed());
UpdateCameraView();
}
} }
void EditorCamera::OnUpdate(TimeStep deltaTime) void EditorCamera::OnUpdate(TimeStep deltaTime)

View File

@ -21,7 +21,7 @@ namespace Prism
EditorCamera() = default; EditorCamera() = default;
EditorCamera(const glm::mat4& projectionMatrix); EditorCamera(const glm::mat4& projectionMatrix);
void Focus(); void Focus(const glm::vec3& focusPoint);
void OnUpdate(TimeStep deltaTime); void OnUpdate(TimeStep deltaTime);
void OnEvent(Event& e); void OnEvent(Event& e);
@ -72,6 +72,9 @@ namespace Prism
float m_Distance; float m_Distance;
// focus
float m_MinFocusDistance = 100.0f;
float m_Pitch, m_Yaw; float m_Pitch, m_Yaw;
}; };

View File

@ -17,13 +17,13 @@ namespace Prism
void ObjectsPanel::OnImGuiRender() void ObjectsPanel::OnImGuiRender()
{ {
static const AssetHandle CubeHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Cube.fbx"); static const AssetHandle CubeHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Cube.fbx");
static const AssetHandle CapsuleHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Capsule.fbx"); static const AssetHandle CapsuleHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Capsule.fbx");
static const AssetHandle SphereHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Sphere.fbx"); static const AssetHandle SphereHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Sphere.fbx");
static const AssetHandle CylinderHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Cylinder.fbx"); static const AssetHandle CylinderHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Cylinder.fbx");
static const AssetHandle TorusHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Torus.fbx"); static const AssetHandle TorusHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Torus.fbx");
static const AssetHandle PlaneHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Plane.fbx"); static const AssetHandle PlaneHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Plane.fbx");
static const AssetHandle ConeHandle = AssetsManager::GetAssetIDForFile("assets/meshes/Default/Cone.fbx"); static const AssetHandle ConeHandle = AssetsManager::GetAssetHandleFromFilePath("assets/meshes/Default/Cone.fbx");
ImGui::Begin("Objects"); ImGui::Begin("Objects");
{ {

View File

@ -15,6 +15,7 @@
#include <glm/gtx/matrix_decompose.hpp> #include <glm/gtx/matrix_decompose.hpp>
#include "Prism/Core/Application.h" #include "Prism/Core/Application.h"
#include "Prism/Core/Math/Math.h"
#include "Prism/Physics/PhysicsLayer.h" #include "Prism/Physics/PhysicsLayer.h"
#include "Prism/Physics/PhysicsWrappers.h" #include "Prism/Physics/PhysicsWrappers.h"
#include "Prism/Renderer/Meshfactory.h" #include "Prism/Renderer/Meshfactory.h"
@ -194,11 +195,17 @@ namespace Prism
{ {
auto& children = previousParent.Children(); auto& children = previousParent.Children();
children.erase(std::remove(children.begin(), children.end(), droppedHandle), children.end()); children.erase(std::remove(children.begin(), children.end(), droppedHandle), children.end());
const glm::mat4 parentTransform = m_Context->GetTransformRelativeToParent(previousParent);
glm::vec3 parentTranslation, parentRotation, parentScale;
Math::DecomposeTransform(parentTransform, parentTranslation, parentRotation, parentScale);
e.Transform().Translation = e.Transform().Translation + parentTranslation;
} }
e.SetParentUUID(0); e.SetParentUUID(0);
PM_CORE_INFO("Unparented Entity!"); PM_CORE_DEBUG("Unparented Entity!");
} }
ImGui::EndDragDropTarget(); ImGui::EndDragDropTarget();
@ -247,7 +254,6 @@ namespace Prism
if (m_SelectionContext) if (m_SelectionContext)
{ {
DrawComponents(m_SelectionContext); DrawComponents(m_SelectionContext);
} }
} }
ImGui::End(); ImGui::End();
@ -329,12 +335,18 @@ namespace Prism
parentChildren.erase(std::remove(parentChildren.begin(), parentChildren.end(), droppedHandle), parentChildren.end()); parentChildren.erase(std::remove(parentChildren.begin(), parentChildren.end(), droppedHandle), parentChildren.end());
} }
const glm::mat4 parentTransform = m_Context->GetTransformRelativeToParent(entity);
glm::vec3 parentTranslation, parentRotation, parentScale;
Math::DecomposeTransform(parentTransform, parentTranslation, parentRotation, parentScale);
e.Transform().Translation = e.Transform().Translation - parentTranslation;
e.SetParentUUID(entity.GetUUID()); e.SetParentUUID(entity.GetUUID());
entity.Children().push_back(droppedHandle); entity.Children().push_back(droppedHandle);
PM_CORE_INFO("Dropping Entity {0} on {1}", (uint64_t)droppedHandle, (uint64_t)entity.GetUUID()); PM_CORE_DEBUG("Dropping Entity {0} on {1}", (uint64_t)droppedHandle, (uint64_t)entity.GetUUID());
} }
PM_CORE_INFO("Dropping Entity {0} on {1}", (uint64_t)droppedHandle, (uint64_t)entity.GetUUID()); PM_CORE_DEBUG("Dropping Entity {0} on {1}", (uint64_t)droppedHandle, (uint64_t)entity.GetUUID());
} }
ImGui::EndDragDropTarget(); ImGui::EndDragDropTarget();
@ -760,6 +772,21 @@ namespace Prism
} }
break; break;
} }
/*
case FieldType::ClassReference:
{
Ref<Asset>* asset = (Ref<Asset>*)(isRuntime ? field.GetRuntimeValueRaw() : field.GetStoredValueRaw());
std::string label = field.Name + "(" + field.TypeName + ")";
if (UI::PropertyAssetReference(label.c_str(), *asset))
{
if (isRuntime)
field.SetRuntimeValueRaw(asset);
else
field.SetStoredValueRaw(asset);
}
break;
}
*/
} }
} }
} }

View File

@ -107,6 +107,16 @@ namespace Prism
return result == 0; return result == 0;
} }
bool FileSystem::PrismMoveFile(const std::string& filepath, const std::string& dest)
{
s_IgnoreNextChange = true;
std::filesystem::path p = filepath;
const std::string destFilePath = dest + "/" + p.filename().string();
const BOOL result = MoveFileA(filepath.c_str(), destFilePath.c_str());
s_IgnoreNextChange = false;
return result != 0;
}
void FileSystem::StartWatching() void FileSystem::StartWatching()
{ {

View File

@ -179,10 +179,10 @@ namespace Prism
// Animation // Animation
bool m_IsAnimated = false; bool m_IsAnimated = false;
bool m_AnimationPlaying = false;
float m_AnimationTime = 0.0f; float m_AnimationTime = 0.0f;
float m_WorldTime = 0.0f; float m_WorldTime = 0.0f;
float m_TimeMultiplier = 1.0f; float m_TimeMultiplier = 1.0f;
bool m_AnimationPlaying = false;
std::string m_FilePath; std::string m_FilePath;
private: private:

View File

@ -39,7 +39,7 @@ namespace Prism
// NOTE: Instead of destroying we could try and enforce all items to be trivally destructible // NOTE: Instead of destroying we could try and enforce all items to be trivally destructible
// however some items like uniforms which contain std::strings still exist for now // however some items like uniforms which contain std::strings still exist for now
// static_assert(std::is_trivially_destructible_v<FuncT>, "FuncT must be trivially destructible"); // static_assert(std::is_trivially_destructible_v<FuncT>, "FuncT must be trivially destructible");
pFunc->~FuncT(); // pFunc->~FuncT();
}; };
auto storageBuffer = GetRenderCommandQueue().Allocate(renderCmd, sizeof(func)); auto storageBuffer = GetRenderCommandQueue().Allocate(renderCmd, sizeof(func));
new (storageBuffer) FuncT(std::forward<FuncT>(func)); new (storageBuffer) FuncT(std::forward<FuncT>(func));

View File

@ -110,7 +110,7 @@ namespace Prism
s_Data.GeoPass = RenderPass::Create(geoRenderPassSpec); s_Data.GeoPass = RenderPass::Create(geoRenderPassSpec);
FramebufferSpecification compFramebufferSpec; FramebufferSpecification compFramebufferSpec;
compFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA8 }; compFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA8 , FramebufferTextureFormat::RGBA8};
compFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; compFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
RenderPassSpecification compRenderPassSpec; RenderPassSpecification compRenderPassSpec;
@ -118,7 +118,7 @@ namespace Prism
s_Data.CompositePass = RenderPass::Create(compRenderPassSpec); s_Data.CompositePass = RenderPass::Create(compRenderPassSpec);
FramebufferSpecification bloomBlurFramebufferSpec; FramebufferSpecification bloomBlurFramebufferSpec;
bloomBlurFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F }; bloomBlurFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F , FramebufferTextureFormat::RGBA8};
bloomBlurFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; bloomBlurFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
RenderPassSpecification bloomBlurRenderPassSpec; RenderPassSpecification bloomBlurRenderPassSpec;
@ -394,7 +394,7 @@ namespace Prism
s_Stats.CompositePass = s_Stats.CompositePassTimer.ElapsedMillis(); s_Stats.CompositePass = s_Stats.CompositePassTimer.ElapsedMillis();
}); });
// BloomBlurPass(); BloomBlurPass();
} }
s_Data.DrawList.clear(); s_Data.DrawList.clear();
@ -409,7 +409,7 @@ namespace Prism
const bool outline = !s_Data.SelectedMeshDrawList.empty(); const bool outline = !s_Data.SelectedMeshDrawList.empty();
const bool collider = !s_Data.ColliderDrawList.empty(); const bool collider = !s_Data.ColliderDrawList.empty();
if (outline || collider) if (outline)
{ {
Renderer::Submit([]() Renderer::Submit([]()
{ {
@ -419,7 +419,7 @@ namespace Prism
Renderer::BeginRenderPass(s_Data.GeoPass); Renderer::BeginRenderPass(s_Data.GeoPass);
if (outline || collider) if (outline)
{ {
Renderer::Submit([]() Renderer::Submit([]()
{ {
@ -506,7 +506,7 @@ namespace Prism
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial); Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
} }
if (collider || outline) if (outline)
{ {
Renderer::Submit([]() Renderer::Submit([]()
{ {
@ -621,8 +621,8 @@ namespace Prism
{ {
Renderer::Submit([]() Renderer::Submit([]()
{ {
glStencilFunc(GL_NOTEQUAL, 1, 0xff); // glStencilFunc(GL_NOTEQUAL, 1, 0xff);
glStencilMask(0); // glStencilMask(0);
glLineWidth(1); glLineWidth(1);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
@ -652,8 +652,8 @@ namespace Prism
Renderer::Submit([]() Renderer::Submit([]()
{ {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glStencilMask(0xff); // glStencilMask(0xff);
glStencilFunc(GL_ALWAYS, 1, 0xff); // glStencilFunc(GL_ALWAYS, 1, 0xff);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
}); });
} }
@ -690,6 +690,7 @@ namespace Prism
// s_Data.CompositeShader->SetFloat2("u_FocusPoint", s_Data.FocusPoint); // s_Data.CompositeShader->SetFloat2("u_FocusPoint", s_Data.FocusPoint);
s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples); s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples);
// s_Data.CompositeShader->SetFloat("u_BloomThreshold", s_Data.BloomThreshold); // s_Data.CompositeShader->SetFloat("u_BloomThreshold", s_Data.BloomThreshold);
s_Data.CompositeShader->SetFloat("u_EnableBloom", s_Data.EnableBloom);
s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture(); s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
Renderer::Submit([]() Renderer::Submit([]()
@ -739,6 +740,7 @@ namespace Prism
{ {
Renderer::BeginRenderPass(s_Data.BloomBlendPass); Renderer::BeginRenderPass(s_Data.BloomBlendPass);
s_Data.BloomBlendShader->Bind(); s_Data.BloomBlendShader->Bind();
auto & adad =s_Data;
s_Data.BloomBlendShader->SetFloat("u_Exposure", s_Data.SceneData.SceneCamera.Camera.GetExposure()); s_Data.BloomBlendShader->SetFloat("u_Exposure", s_Data.SceneData.SceneCamera.Camera.GetExposure());
s_Data.BloomBlendShader->SetBool("u_EnableBloom", s_Data.EnableBloom); s_Data.BloomBlendShader->SetBool("u_EnableBloom", s_Data.EnableBloom);

View File

@ -32,4 +32,9 @@ namespace Prism
{ {
return entity.IsAncesterOf(*this); return entity.IsAncesterOf(*this);
} }
bool Entity::HasParent()
{
return m_Scene->FindEntityByUUID(GetParentUUID());
}
} }

View File

@ -73,6 +73,7 @@ namespace Prism
bool IsAncesterOf(Entity entity); bool IsAncesterOf(Entity entity);
bool IsDescendantOf(Entity entity) const; bool IsDescendantOf(Entity entity) const;
bool HasParent();
UUID GetUUID() { return GetComponent<IDComponent>().ID; } UUID GetUUID() { return GetComponent<IDComponent>().ID; }

View File

@ -267,6 +267,7 @@ namespace Prism
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity); auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
m_Environment = skyLightComponent.SceneEnvironment; m_Environment = skyLightComponent.SceneEnvironment;
m_EnvironmentIntensity = skyLightComponent.Intensity; m_EnvironmentIntensity = skyLightComponent.Intensity;
if (m_Environment)
SetSkybox(m_Environment->RadianceMap); SetSkybox(m_Environment->RadianceMap);
} }
} }

View File

@ -572,6 +572,7 @@ namespace Prism
std::string sceneName = data["Scene"].as<std::string>(); std::string sceneName = data["Scene"].as<std::string>();
PM_CORE_INFO("Deserializing scene '{0}'", sceneName); PM_CORE_INFO("Deserializing scene '{0}'", sceneName);
/*
auto environment = data["Environment"]; auto environment = data["Environment"];
if (environment) if (environment)
{ {
@ -587,6 +588,7 @@ namespace Prism
light.Multiplier = lightNode["Multiplier"].as<float>(); light.Multiplier = lightNode["Multiplier"].as<float>();
} }
} }
*/
auto entities = data["Entities"]; auto entities = data["Entities"];
if (entities) if (entities)
@ -664,14 +666,16 @@ namespace Prism
for (auto field : storedFields) for (auto field : storedFields)
{ {
auto name = field["Name"].as<std::string>(); auto name = field["Name"].as<std::string>();
std::string typeName = field["TypeName"] ? field["TypeName"].as<std::string>() : "";
auto type = static_cast<FieldType>(field["Type"].as<uint32_t>()); auto type = static_cast<FieldType>(field["Type"].as<uint32_t>());
EntityInstanceData& data = ScriptEngine::GetEntityInstanceData(m_Scene->GetUUID(), uuid); EntityInstanceData& data = ScriptEngine::GetEntityInstanceData(m_Scene->GetUUID(), uuid);
auto& moduleFieldMap = data.ModuleFieldMap; auto& moduleFieldMap = data.ModuleFieldMap;
auto& publicFields = moduleFieldMap[moduleName]; auto& publicFields = moduleFieldMap[moduleName];
if (publicFields.find(name) == publicFields.end()) if (publicFields.find(name) == publicFields.end())
{ {
// PublicField pf = { name, type };
// publicFields.emplace(name, std::move(pf)); PublicField pf = { name, typeName, type };
publicFields.emplace(name, std::move(pf));
PM_CORE_WARN("Script field '{0}' not found in current Script file! ignore this.", name); PM_CORE_WARN("Script field '{0}' not found in current Script file! ignore this.", name);
continue; continue;
} }
@ -726,7 +730,7 @@ namespace Prism
if (meshComponent["AssetPath"]) if (meshComponent["AssetPath"])
{ {
const std::string assetFilePath = meshComponent["AssetPath"].as<std::string>(); const std::string assetFilePath = meshComponent["AssetPath"].as<std::string>();
assetID = AssetsManager::GetAssetIDForFile(assetFilePath); assetID = AssetsManager::GetAssetHandleFromFilePath(filepath);
} }
else else
{ {
@ -756,7 +760,7 @@ namespace Prism
if (skyLightComponent["EnvironmentAssetPath"]) if (skyLightComponent["EnvironmentAssetPath"])
{ {
const std::string filePath = skyLightComponent["EnvironmentAssetPath"].as<std::string>(); const std::string filePath = skyLightComponent["EnvironmentAssetPath"].as<std::string>();
assetHandle = AssetsManager::GetAssetIDForFile(filePath); assetHandle = AssetsManager::GetAssetHandleFromFilePath(filepath);
} }
else else
{ {
@ -906,7 +910,7 @@ namespace Prism
if (meshComponent["AssetPath"]) if (meshComponent["AssetPath"])
{ {
const auto assetFilePath = meshComponent["AssetPath"].as<std::string>(); const auto assetFilePath = meshComponent["AssetPath"].as<std::string>();
assetID = AssetsManager::GetAssetIDForFile(assetFilePath); assetID = AssetsManager::GetAssetHandleFromFilePath(filepath);
} }
else else
{ {

View File

@ -303,10 +303,10 @@ namespace Prism
case FieldType::Float: return 4; case FieldType::Float: return 4;
case FieldType::Int: return 4; case FieldType::Int: return 4;
case FieldType::UnsignedInt: return 4; case FieldType::UnsignedInt: return 4;
// case FieldType::String: return 8; // TODO
case FieldType::Vec2: return 4 * 2; case FieldType::Vec2: return 4 * 2;
case FieldType::Vec3: return 4 * 3; case FieldType::Vec3: return 4 * 3;
case FieldType::Vec4: return 4 * 4; case FieldType::Vec4: return 4 * 4;
case FieldType::ClassReference: return 4;
} }
PM_CORE_ASSERT(false, "Unknown field type!"); PM_CORE_ASSERT(false, "Unknown field type!");
return 0; return 0;
@ -321,6 +321,7 @@ namespace Prism
case MONO_TYPE_I4: return FieldType::Int; case MONO_TYPE_I4: return FieldType::Int;
case MONO_TYPE_U4: return FieldType::UnsignedInt; case MONO_TYPE_U4: return FieldType::UnsignedInt;
case MONO_TYPE_STRING: return FieldType::String; case MONO_TYPE_STRING: return FieldType::String;
case MONO_TYPE_CLASS: return FieldType::ClassReference;
case MONO_TYPE_VALUETYPE: case MONO_TYPE_VALUETYPE:
{ {
const char* name = mono_type_get_name(monoType); const char* name = mono_type_get_name(monoType);
@ -355,12 +356,20 @@ namespace Prism
return buffer; return buffer;
} }
void PublicField::SetStoredValue_Internal(void* value) const void PublicField::SetStoredValue_Internal(const void* value) const
{
if (Type == FieldType::ClassReference)
{
//m_StoredValueBuffer = (uint8_t*)value;
}
else
{ {
const uint32_t size = GetFieldSize(Type); const uint32_t size = GetFieldSize(Type);
memcpy(m_StoredValueBuffer, value, size); memcpy(m_StoredValueBuffer, value, size);
} }
}
void PublicField::GetStoredValue_Internal(void* outValue) const void PublicField::GetStoredValue_Internal(void* outValue) const
{ {
const uint32_t size = GetFieldSize(Type); const uint32_t size = GetFieldSize(Type);
@ -750,18 +759,32 @@ namespace Prism
MonoType* fieldType = mono_field_get_type(iter); MonoType* fieldType = mono_field_get_type(iter);
const FieldType prismFieldType = GetPrismFieldType(fieldType); const FieldType prismFieldType = GetPrismFieldType(fieldType);
if (prismFieldType == FieldType::ClassReference)
continue;
// TODO: Attributes // TODO: Attributes
MonoCustomAttrInfo* attr = mono_custom_attrs_from_field(scriptClass.Class, iter); MonoCustomAttrInfo* attr = mono_custom_attrs_from_field(scriptClass.Class, iter);
char* typeName = mono_type_get_name(fieldType);
if (oldFields.find(name) != oldFields.end()) if (oldFields.find(name) != oldFields.end())
{ {
fieldMap.emplace(name, std::move(oldFields.at(name))); fieldMap.emplace(name, std::move(oldFields.at(name)));
} }
else else
{ {
PublicField field = { name, prismFieldType }; PublicField field = { name, typeName, prismFieldType };
field.m_EntityInstance = &entityInstance; field.m_EntityInstance = &entityInstance;
field.m_MonoClassField = iter; field.m_MonoClassField = iter;
/*
if (field.Type == FieldType::ClassReference)
{
const auto asset = new Ref<Asset>();
field.SetStoredValueRaw(asset);
}
*/
fieldMap.emplace(name, std::move(field)); fieldMap.emplace(name, std::move(field));
} }
} }
@ -874,8 +897,8 @@ namespace Prism
return mono_gchandle_get_target(Handle); return mono_gchandle_get_target(Handle);
} }
PublicField::PublicField(const std::string& name, FieldType type) PublicField::PublicField(const std::string& name, const std::string& typeName, const FieldType type)
: Name(name), Type(type) : Name(name), TypeName(typeName), Type(type)
{ {
m_StoredValueBuffer = AllocateBuffer(type); m_StoredValueBuffer = AllocateBuffer(type);
} }
@ -883,6 +906,7 @@ namespace Prism
PublicField::PublicField(PublicField&& other) PublicField::PublicField(PublicField&& other)
{ {
Name = std::move(other.Name); Name = std::move(other.Name);
TypeName = std::move(other.TypeName);
Type = other.Type; Type = other.Type;
m_EntityInstance = other.m_EntityInstance; m_EntityInstance = other.m_EntityInstance;
m_MonoClassField = other.m_MonoClassField; m_MonoClassField = other.m_MonoClassField;
@ -901,17 +925,77 @@ namespace Prism
void PublicField::CopyStoredValueToRuntime() void PublicField::CopyStoredValueToRuntime()
{ {
PM_CORE_ASSERT(m_EntityInstance->GetInstance()); PM_CORE_ASSERT(m_EntityInstance->GetInstance());
if (Type == FieldType::ClassReference)
{
// Create Managed Object
void* params[] = {
&m_StoredValueBuffer
};
MonoObject* obj = ScriptEngine::Construct(TypeName + ":.ctor(intptr)", true, params);
mono_field_set_value(m_EntityInstance->GetInstance(), m_MonoClassField, obj);
}
else
{
mono_field_set_value(m_EntityInstance->GetInstance(), m_MonoClassField, m_StoredValueBuffer); mono_field_set_value(m_EntityInstance->GetInstance(), m_MonoClassField, m_StoredValueBuffer);
} }
}
bool PublicField::IsRuntimeAvailable() const bool PublicField::IsRuntimeAvailable() const
{ {
return m_EntityInstance->Handle != 0; return m_EntityInstance->Handle != 0;
} }
void PublicField::SetStoredValueRaw(void* src) void PublicField::SetStoredValueRaw(void* src)
{
if (Type == FieldType::ClassReference)
{
m_StoredValueBuffer = (uint8_t*)src;
}
else
{ {
uint32_t size = GetFieldSize(Type); uint32_t size = GetFieldSize(Type);
memcpy(m_StoredValueBuffer, src, size); memcpy(m_StoredValueBuffer, src, size);
} }
}
void PublicField::SetRuntimeValueRaw(void* src)
{
if (Type == FieldType::ClassReference)
{
m_StoredValueBuffer = (uint8_t*)src;
}
else
{
uint32_t size = GetFieldSize(Type);
memcpy(m_StoredValueBuffer, src, size);
}
}
void* PublicField::GetRuntimeValueRaw()
{
PM_CORE_ASSERT(m_EntityInstance->GetInstance());
if (Type == FieldType::ClassReference)
{
MonoObject* instance;
mono_field_get_value(m_EntityInstance->GetInstance(), m_MonoClassField, &instance);
if (!instance)
return nullptr;
MonoClassField* field = mono_class_get_field_from_name(mono_object_get_class(instance), "m_UnmanagedInstance");
int* value;
mono_field_get_value(instance, field, &value);
return value;
}
else
{
uint8_t* outValue = nullptr;
mono_field_get_value(m_EntityInstance->GetInstance(), m_MonoClassField, outValue);
return outValue;
}
}
} }

View File

@ -17,7 +17,7 @@ namespace Prism
{ {
enum class FieldType enum class FieldType
{ {
None = 0, Float, Int, UnsignedInt, String, Vec2, Vec3, Vec4 None = 0, Float, Int, UnsignedInt, String, Vec2, Vec3, Vec4, ClassReference
}; };
const char* FieldTypeToString(FieldType type); const char* FieldTypeToString(FieldType type);
@ -36,9 +36,10 @@ namespace Prism
struct PublicField struct PublicField
{ {
std::string Name; std::string Name;
std::string TypeName;
FieldType Type; FieldType Type;
PublicField(const std::string& name, FieldType type); PublicField(const std::string& name, const std::string& typeName, FieldType type);
PublicField(const PublicField&) = delete; PublicField(const PublicField&) = delete;
PublicField(PublicField&& other); PublicField(PublicField&& other);
~PublicField(); ~PublicField();
@ -75,13 +76,18 @@ namespace Prism
} }
void SetStoredValueRaw(void* src); void SetStoredValueRaw(void* src);
void* GetStoredValueRaw() { return m_StoredValueBuffer; }
void SetRuntimeValueRaw(void* src);
void* GetRuntimeValueRaw();
private: private:
EntityInstance* m_EntityInstance; EntityInstance* m_EntityInstance;
MonoClassField* m_MonoClassField; MonoClassField* m_MonoClassField;
uint8_t* m_StoredValueBuffer = nullptr; uint8_t* m_StoredValueBuffer = nullptr;
uint8_t* AllocateBuffer(FieldType type); uint8_t* AllocateBuffer(FieldType type);
void SetStoredValue_Internal(void* value) const; void SetStoredValue_Internal(const void* value) const;
void GetStoredValue_Internal(void* outValue) const; void GetStoredValue_Internal(void* outValue) const;
void SetRuntimeValue_Internal(void* value) const; void SetRuntimeValue_Internal(void* value) const;
void GetRuntimeValue_Internal(void* outValue) const; void GetRuntimeValue_Internal(void* outValue) const;

View File

@ -33,6 +33,7 @@ namespace Prism
static bool Exists(const std::string& filepath); static bool Exists(const std::string& filepath);
static std::string Rename(const std::string& filepath, const std::string& newName); static std::string Rename(const std::string& filepath, const std::string& newName);
static bool PrismDeleteFile(const std::string& filepath); static bool PrismDeleteFile(const std::string& filepath);
static bool PrismMoveFile(const std::string& filepath, const std::string& dest);
static void SetChangeCallback(const FileSystemChangedCallbackFn& callback); static void SetChangeCallback(const FileSystemChangedCallbackFn& callback);
static void StartWatching(); static void StartWatching();