Skip to content

Commit

Permalink
# Scene Layer Support
Browse files Browse the repository at this point in the history
## User Guide

- Layers are separate documents (ezLayerDocument) that can be added to a scene to allow for various parts of a scene to be loaded / unloaded and help organize bigger scenes. Right now, all layers are still baked into the parent scene on export. Engine support for layers will be added later.
- A new layer panel is added that allows the user to add / remove layers, load / unload and toggle their visibility. Layers can be dragged around to change their order and game objects can be dragged onto a layer to move them between layers.
- Only one layer can be modified at any given time. By selecting the layer in the layer panel it becomes active and its content is shown in the scene tree.
- As layers are supposed to be unloadable there can't be any object / component references across layers.
- Multi-selection in the viewport will only allow selecting objects from the active layer. Single selection will automatically swtich the active layer to the one corresponding to the selected object.
- Ctrl+S is changed to save the active layer within the scene.
- Layer names map directly to their file names which are stored in the *[SceneName]_data folder*. To rename a layer, its file has to be renamed.

## Layers Implementation Details

- Before this PR, every document window mapped to exactly one document. The concept of a main / sub-document was added similiar to their asset counterparts a sub-asset is part of another document, i.e. the main document that controls it. ezDocument was extended with functions to query the type of document and the currently active sub-document that is being edited.
- To keep the affect on exisiting UI code to a minimum, not all code was changed to be aware that a document window can map to multipe documents. Instead, the ezCommandHistory, ezDocumentObjectManager, ezObjectMetaData and ezSelectionManager had their data moved into a separate storage class and whenever the active layer of a scene changes the content of the afore mentioned classes of the scene is replaced with the content of the active layer. Thus, code that is not layer ware will always work on the active layer. The side-effect of this is that changes must only be done to a layer when it is active as otherwise certain features would break.
- ezScene2Document::InitializeAfterLoadingAndSaving will swap all the document parts (object manager, selection, undo history) against new instances. Thus, everything that accessed those during load gets the 'real' document content. Afterwards, every access goes against the adapter versions that redirect to the active document. In the ezScene2Document dtor, the swap is reversed to make sure everything deints on the same object instances (removing event subs etc).
- Opening / creating a document allows for the context object to be passed into the ctor, allowing for a layer to be informed what the parent scene is.
- Document is aware now that it and its window can host other documents as clients or that is a client doc hosted inside another doc / window.

## Scene Implementation Details

- Scene has its class changed to ezScene2Document and ezSceneDocument has become a base class. Will be renamed in a later PR to keep the diff to a minimum.
- Added enum to differentiate scene, prefab, layer.
- The scene graph tree is now stackable. When the active layer changes the corresponding widget is brought to the front. This means that all view state is preserved when switching the active layer.
  - The only tricky part is the actual scene tree as the scene's content is constatly swapped out we must not rely on the scene pointer in the model. Thus, ezQtGameObjectAdapter / ezQtGameObjectModel needed extensive changes to not rely on the doc pointer to get access to various parts of the doc (selection, object manager, meta data storage).
- Added BeforeReset / AfterReset events to ezDocumentObjectManager. Used when switching the content of the scene when switching layers. So instead of firing object removed / added for every root object there are just two messages: BeforeReset / AfterReset.
- The scene has a custom ezSceneSelectionContext which allows it to switch layers automatically when selecting an element in the viewport that belongs to a different layer.
- Add support for setting a custom root node in a tree model. This allows for the tree model to be used for e.g. layers which are stored in a separate property on the root node.
- Each scene document type now has a custom ezSceneDocumentSettingsBase derived settings class (ezSceneDocumentSettings, ezPrefabDocumentSettings, ezLayerDocumentSettings, ). A patch changes ezSceneDocumentSettings to ezPrefabDocumentSettings as only prefabs use them until now. EnsureSettingsObjectExist will switch the settings object to the correct type when loading old documents.
- ezQtLayerAdapter implements the custom layer visualization. Supports layer loaded / visible state change with small buttons in the item cell.
- Layer lifetime in editor is coupled to the parent scene. I.e., closing a scene also closes all layers.
- Setting reference to object in other layer displays a status message that this is not allowed.
- RMB -> attach to this will show an error if the target object is in another layer.

## Engine Context Implementation Details

- Layers have runtime contexts to mirror their content.
- A DocumentMetaData object can be sent to the engine process on context creation. This allows for the layer context to be informed which scene it belongs to so that all its content is created in the same ezWorld.
- Differentiating between objects of different layers in the ezWorld is implemented by tagging each ezGameObject with a tag in the form of "Layer_1". Layer guids are remapped to indices to prevent tag regstry polution. Thus, all documents share the same tags.
- Hiding layers is done by adding the appropriate exclude tags to the view.
- Allow a layer to be opened individually by posing as a scene. To do this the engine context needs to be redirected to ezSceneContext instead of ezLayerContext which is done by a custom function "AllocateContext" which can be implemented per engine context and gets passed in the ezDocumentOpenMsgToEngine.
- Pick IDs are unique across the scene and its layers as they all share the same m_uiNextComponentPickingID.
- ezEngineProcessDocumentContext::m_pWorld is no longer a unique ptr to support sharing the world between scene and layers.

## Misc changes and fixes

- ezDragDropInfo now stores the adapter of the target parent object to allow querying under which property the dragged object can be stored.
- Fixed the Qt selection so that it inherits the selection state from the underlying selection manager on creation.
- Added Edit > PasteAtOriginalLocation to place objects at the exact same global position they were copied from.
- Better detection for AMD graphics cards to switch some image compare sets.
- Added **EZ_TEST_STATUS** macro to verify ezStatus success and output its error message on failure.
- Fixed bug when calling a function via reflection that returns a pointer.
- Fixed wrong position dragging objects to other layers which also affected copy&paste in general. This is done now by storing the global transform in the serialized nodes. ezSceneDocument::PasteAtOrignalPosition will restore global position if present.
- Fixed icons in the scene tree not being visible at the start.
- Fixed random crash on shadow pool (shadow pool views can contain dead ezWorld ptrs.)
- TypeScript asset was accidentally marked as having an engine connection.
- Fixed relative item order to remain the same after copy&paste or moving between layers.
- Fixed item position under the parent's children when switchting between editor and engine prefabs types.
- Added support to unmap actions from an action mapping. Used to e.g. remove the standard save action again in the scene and replace it with the save active layer action.
- Shadow pool views inherit the exclusion tags of the view that spawned them. This is e.g. used to hide the shadows of hidden layers in the scene.
- Added helper function ezGraphPatchContext::RenameClass for easier patch writing when renaming classes.
- Physics scene now uses layers.

## Unit tests

- ezEditorTest class was extended with various helper functions to test various drag&drop operations.
- Expanded GameObjectReferences test to also test the functionality within a layer.
- Added scene layer operations test.
- Added basic prefab test.
  • Loading branch information
Sanakan8472 committed Sep 26, 2021
1 parent 69440c9 commit 98809a4
Show file tree
Hide file tree
Showing 208 changed files with 5,438 additions and 898 deletions.
32 changes: 27 additions & 5 deletions Code/Editor/EditorEngineProcess/EngineProcGameApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,10 @@ void ezEngineProcessGameApplication::EventHandlerIPC(const ezEngineProcessCommun
if (const auto* pMsg = ezDynamicCast<const ezDocumentClearMsgToEngine*>(e.m_pMessage))
{
ezEngineProcessDocumentContext* pDocumentContext = ezEngineProcessDocumentContext::GetDocumentContext(pMsg->m_DocumentGuid);
pDocumentContext->ClearExistingObjects();
if (pDocumentContext)
{
pDocumentContext->ClearExistingObjects();
}
return;
}

Expand Down Expand Up @@ -417,10 +420,29 @@ ezEngineProcessDocumentContext* ezEngineProcessGameApplication::CreateDocumentCo
if (sDocTypes.FindSubString(sRequestedType) != nullptr)
{
ezLog::Dev("Created Context of type '{0}' for '{1}'", pRtti->GetTypeName(), pMsg->m_sDocumentType);

pDocumentContext = pRtti->GetAllocator()->Allocate<ezEngineProcessDocumentContext>();

ezEngineProcessDocumentContext::AddDocumentContext(pMsg->m_DocumentGuid, pDocumentContext, &m_IPC);
for (ezAbstractFunctionProperty* pFunc : pRtti->GetFunctions())
{
if (ezStringUtils::IsEqual(pFunc->GetPropertyName(), "AllocateContext"))
{
ezVariant res;
ezHybridArray<ezVariant, 1> params;
params.PushBack(pMsg);
pFunc->Execute(nullptr, params, res);
if (res.IsA<ezEngineProcessDocumentContext*>())
{
pDocumentContext = res.Get<ezEngineProcessDocumentContext*>();
}
else
{
ezLog::Error("Failed to call custom allocator '{}::{}'.", pRtti->GetTypeName(), pFunc->GetPropertyName());
}
}
}

if (!pDocumentContext)
pDocumentContext = pRtti->GetAllocator()->Allocate<ezEngineProcessDocumentContext>();

ezEngineProcessDocumentContext::AddDocumentContext(pMsg->m_DocumentGuid, pMsg->m_DocumentMetaData, pDocumentContext, &m_IPC);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@ class ezExportDocumentMsgToEngine;
class ezCreateThumbnailMsgToEngine;
struct ezResourceEvent;

struct ezEngineProcessDocumentContextFlags
{
typedef ezUInt8 StorageType;

enum Enum
{
None = 0,
CreateWorld = EZ_BIT(0),
Default = CreateWorld
};

struct Bits
{
StorageType CreateWorld : 1;
};
};
EZ_DECLARE_FLAGS_OPERATORS(ezEngineProcessDocumentContextFlags);

/// \brief A document context is the counter part to an editor document on the engine side.
///
/// For every document in the editor that requires engine output (rendering, picking, etc.), there is a ezEngineProcessDocumentContext
Expand All @@ -24,17 +42,17 @@ class EZ_EDITORENGINEPROCESSFRAMEWORK_DLL ezEngineProcessDocumentContext : publi
EZ_ADD_DYNAMIC_REFLECTION(ezEngineProcessDocumentContext, ezReflectedClass);

public:
ezEngineProcessDocumentContext();
ezEngineProcessDocumentContext(ezBitflags<ezEngineProcessDocumentContextFlags> flags = ezEngineProcessDocumentContextFlags::Default);
virtual ~ezEngineProcessDocumentContext();

void Initialize(const ezUuid& DocumentGuid, ezEngineProcessCommunicationChannel* pIPC);
virtual void Initialize(const ezUuid& DocumentGuid, const ezVariant& metaData, ezEngineProcessCommunicationChannel* pIPC);
void Deinitialize();

void SendProcessMessage(ezProcessMessage* pMsg = nullptr);
virtual void HandleMessage(const ezEditorEngineDocumentMsg* pMsg);

static ezEngineProcessDocumentContext* GetDocumentContext(ezUuid guid);
static void AddDocumentContext(ezUuid guid, ezEngineProcessDocumentContext* pView, ezEngineProcessCommunicationChannel* pIPC);
static void AddDocumentContext(ezUuid guid, const ezVariant& metaData, ezEngineProcessDocumentContext* pView, ezEngineProcessCommunicationChannel* pIPC);
static bool PendingOperationsInProgress();
static void UpdateDocumentContexts();
static void DestroyDocumentContext(ezUuid guid);
Expand All @@ -52,7 +70,10 @@ class EZ_EDITORENGINEPROCESSFRAMEWORK_DLL ezEngineProcessDocumentContext : publi
ezIPCObjectMirrorEngine m_Mirror;
ezWorldRttiConverterContext m_Context; // TODO: Move actual context into the EngineProcessDocumentContext

ezWorld* GetWorld() const { return m_pWorld.Borrow(); }
ezWorld* GetWorld() const { return m_pWorld; }

/// \brief Tries to resolve a 'reference' (given in pData) to an ezGameObject.
virtual ezGameObjectHandle ResolveStringToGameObjectHandle(const void* pString, ezComponentHandle hThis, const char* szProperty) const;

protected:
virtual void OnInitialize();
Expand Down Expand Up @@ -100,7 +121,7 @@ class EZ_EDITORENGINEPROCESSFRAMEWORK_DLL ezEngineProcessDocumentContext : publi
/// \brief Called before a thumbnail context is destroyed. Used for cleanup of what was done in OnThumbnailViewContextCreated()
virtual void OnDestroyThumbnailViewContext();

ezUniquePtr<ezWorld> m_pWorld;
ezWorld* m_pWorld;

/// \brief Sets or removes the given tag on the object and optionally all children
void SetTagOnObject(const ezUuid& object, const char* szTag, bool bSet, bool recursive);
Expand All @@ -116,9 +137,6 @@ class EZ_EDITORENGINEPROCESSFRAMEWORK_DLL ezEngineProcessDocumentContext : publi
return uiView >= m_ViewContexts.GetCount() ? nullptr : m_ViewContexts[uiView];
}

/// \brief Tries to resolve a 'reference' (given in pData) to an ezGameObject.
ezGameObjectHandle ResolveStringToGameObjectHandle(const void* pString, ezComponentHandle hThis, const char* szProperty) const;

private:
friend class ezEditorEngineSyncObject;

Expand All @@ -136,7 +154,10 @@ class EZ_EDITORENGINEPROCESSFRAMEWORK_DLL ezEngineProcessDocumentContext : publi
/// Removes all sync objects that are tied to this context
void CleanUpContextSyncObjects();

protected:
ezBitflags<ezEngineProcessDocumentContextFlags> m_flags;
ezUuid m_DocumentGuid;
ezVariant m_MetaData;

ezEngineProcessCommunicationChannel* m_pIPC = nullptr;
ezHybridArray<ezEngineProcessViewContext*, 4> m_ViewContexts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class EZ_EDITORENGINEPROCESSFRAMEWORK_DLL ezDocumentOpenMsgToEngine : public ezE

bool m_bDocumentOpen;
ezString m_sDocumentType;
ezVariant m_DocumentMetaData;
};

/// \brief Used to reset the engine side to an empty document before sending the full document state over
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ ezEngineProcessDocumentContext* ezEngineProcessDocumentContext::GetDocumentConte
return pResult;
}

void ezEngineProcessDocumentContext::AddDocumentContext(ezUuid guid, ezEngineProcessDocumentContext* pContext, ezEngineProcessCommunicationChannel* pIPC)
void ezEngineProcessDocumentContext::AddDocumentContext(ezUuid guid, const ezVariant& metaData, ezEngineProcessDocumentContext* pContext, ezEngineProcessCommunicationChannel* pIPC)
{
EZ_ASSERT_DEV(!s_DocumentContexts.Contains(guid), "Cannot add a view with an index that already exists");
s_DocumentContexts[guid] = pContext;

pContext->Initialize(guid, pIPC);
pContext->Initialize(guid, metaData, pIPC);
}

bool ezEngineProcessDocumentContext::PendingOperationsInProgress()
Expand Down Expand Up @@ -91,7 +91,8 @@ ezBoundingBoxSphere ezEngineProcessDocumentContext::GetWorldBounds(ezWorld* pWor
return bounds;
}

ezEngineProcessDocumentContext::ezEngineProcessDocumentContext()
ezEngineProcessDocumentContext::ezEngineProcessDocumentContext(ezBitflags<ezEngineProcessDocumentContextFlags> flags)
: m_flags(flags)
{
m_Context.m_Events.AddEventHandler(ezMakeDelegate(&ezEngineProcessDocumentContext::WorldRttiConverterContextEventHandler, this));
}
Expand All @@ -103,35 +104,41 @@ ezEngineProcessDocumentContext::~ezEngineProcessDocumentContext()
m_Context.m_Events.RemoveEventHandler(ezMakeDelegate(&ezEngineProcessDocumentContext::WorldRttiConverterContextEventHandler, this));
}

void ezEngineProcessDocumentContext::Initialize(const ezUuid& DocumentGuid, ezEngineProcessCommunicationChannel* pIPC)
void ezEngineProcessDocumentContext::Initialize(const ezUuid& DocumentGuid, const ezVariant& metaData, ezEngineProcessCommunicationChannel* pIPC)
{
m_DocumentGuid = DocumentGuid;
m_MetaData = metaData;
m_pIPC = pIPC;

ezStringBuilder tmp;
ezWorldDesc desc(ezConversionUtils::ToString(m_DocumentGuid, tmp));
desc.m_bReportErrorWhenStaticObjectMoves = false;

m_pWorld = EZ_DEFAULT_NEW(ezWorld, desc);
m_pWorld->SetGameObjectReferenceResolver(ezMakeDelegate(&ezEngineProcessDocumentContext::ResolveStringToGameObjectHandle, this));
if (m_flags.IsSet(ezEngineProcessDocumentContextFlags::CreateWorld))
{
ezStringBuilder tmp;
ezWorldDesc desc(ezConversionUtils::ToString(m_DocumentGuid, tmp));
desc.m_bReportErrorWhenStaticObjectMoves = false;

m_Context.m_pWorld = m_pWorld.Borrow();
m_Mirror.InitReceiver(&m_Context);
m_pWorld = EZ_DEFAULT_NEW(ezWorld, desc);
m_pWorld->SetGameObjectReferenceResolver(ezMakeDelegate(&ezEngineProcessDocumentContext::ResolveStringToGameObjectHandle, this));

m_Context.m_pWorld = m_pWorld;
m_Mirror.InitReceiver(&m_Context);
}
OnInitialize();
}

void ezEngineProcessDocumentContext::Deinitialize()
{
OnDeinitialize();

ClearViewContexts();
m_Mirror.Clear();
m_Mirror.DeInit();
m_Context.Clear();

OnDeinitialize();

CleanUpContextSyncObjects();

if (m_flags.IsSet(ezEngineProcessDocumentContextFlags::CreateWorld))
{
EZ_DEFAULT_DELETE(m_pWorld);
}
m_pWorld = nullptr;
}

Expand Down Expand Up @@ -370,7 +377,7 @@ void ezEngineProcessDocumentContext::Reset()

Deinitialize();

Initialize(guid, ipc);
Initialize(guid, m_MetaData, ipc);
}

void ezEngineProcessDocumentContext::ClearExistingObjects()
Expand Down Expand Up @@ -912,13 +919,13 @@ void ezEngineProcessDocumentContext::UpdateSyncObjects()

EZ_LOCK(m_pWorld->GetWriteMarker());

if (pSyncObject->SetupForEngine(m_pWorld.Borrow(), m_Context.m_uiNextComponentPickingID))
if (pSyncObject->SetupForEngine(m_pWorld, m_Context.m_uiNextComponentPickingID))
{
m_Context.m_OtherPickingMap.RegisterObject(pSyncObject->GetGuid(), m_Context.m_uiNextComponentPickingID);
++m_Context.m_uiNextComponentPickingID;
}

pSyncObject->UpdateForEngine(m_pWorld.Borrow());
pSyncObject->UpdateForEngine(m_pWorld);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ EZ_BEGIN_DYNAMIC_REFLECTED_TYPE(ezDocumentOpenMsgToEngine, 1, ezRTTIDefaultAlloc
EZ_BEGIN_PROPERTIES
{
EZ_MEMBER_PROPERTY("DocumentOpen", m_bDocumentOpen),
EZ_MEMBER_PROPERTY("DocumentType", m_sDocumentType),
EZ_MEMBER_PROPERTY("DocumentType", m_sDocumentType),
EZ_MEMBER_PROPERTY("DocumentMetaData", m_DocumentMetaData),
}
EZ_END_PROPERTIES;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <EditorFramework/EditorFrameworkPCH.h>

#include <EditorFramework/Actions/ViewActions.h>
#include <EditorFramework/Assets/AssetDocument.h>
#include <EditorFramework/DocumentWindow/EngineViewWidget.moc.h>

ezActionDescriptorHandle ezViewActions::s_hRenderMode;
Expand Down Expand Up @@ -143,15 +144,15 @@ void ezViewAction::Execute(const ezVariant& value)
{
case ezViewAction::ButtonType::ActivateRemoteProcess:
{
ezEditorEngineProcessConnection::GetSingleton()->ActivateRemoteProcess(m_Context.m_pDocument, pView->GetViewID());
ezEditorEngineProcessConnection::GetSingleton()->ActivateRemoteProcess(ezDynamicCast<ezAssetDocument*>(m_Context.m_pDocument), pView->GetViewID());
}
break;

case ezViewAction::ButtonType::LinkDeviceCamera:
{
pView->m_pViewConfig->m_bUseCameraTransformOnDevice = !pView->m_pViewConfig->m_bUseCameraTransformOnDevice;
SetChecked(pView->m_pViewConfig->m_bUseCameraTransformOnDevice);
ezEditorEngineProcessConnection::GetSingleton()->ActivateRemoteProcess(m_Context.m_pDocument, pView->GetViewID());
ezEditorEngineProcessConnection::GetSingleton()->ActivateRemoteProcess(ezDynamicCast<ezAssetDocument*>(m_Context.m_pDocument), pView->GetViewID());
}
break;
}
Expand Down
3 changes: 3 additions & 0 deletions Code/Editor/EditorFramework/Assets/AssetDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ class EZ_EDITORFRAMEWORK_DLL ezAssetDocument : public ezDocument

/// \brief Returns the current state of the engine process side of this document.
EngineStatus GetEngineStatus() const { return m_EngineStatus; }

/// \brief Passed into ezEngineProcessDocumentContext::Initialize on the engine process side. Allows the document to provide additional data to the engine process during context creation.
virtual ezVariant GetCreateEngineMetaData() const { return ezVariant(); }

/// \brief Sends a message to the corresponding ezEngineProcessDocumentContext on the engine process.
void SendMessageToEngine(ezEditorEngineDocumentMsg* pMessage) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ void ezAssetDocument::InitializeAfterLoadingAndSaving()
void ezAssetDocument::AddPrefabDependencies(const ezDocumentObject* pObject, ezAssetDocumentInfo* pInfo) const
{
{
const ezDocumentObjectMetaData* pMeta = m_DocumentObjectMetaData.BeginReadMetaData(pObject->GetGuid());
const ezDocumentObjectMetaData* pMeta = m_DocumentObjectMetaData->BeginReadMetaData(pObject->GetGuid());

if (pMeta->m_CreateFromPrefab.IsValid())
{
ezStringBuilder tmp;
pInfo->m_AssetTransformDependencies.Insert(ezConversionUtils::ToString(pMeta->m_CreateFromPrefab, tmp));
}

m_DocumentObjectMetaData.EndReadMetaData();
m_DocumentObjectMetaData->EndReadMetaData();
}


Expand All @@ -176,7 +176,7 @@ void ezAssetDocument::AddPrefabDependencies(const ezDocumentObject* pObject, ezA
void ezAssetDocument::AddReferences(const ezDocumentObject* pObject, ezAssetDocumentInfo* pInfo, bool bInsidePrefab) const
{
{
const ezDocumentObjectMetaData* pMeta = m_DocumentObjectMetaData.BeginReadMetaData(pObject->GetGuid());
const ezDocumentObjectMetaData* pMeta = m_DocumentObjectMetaData->BeginReadMetaData(pObject->GetGuid());

if (pMeta->m_CreateFromPrefab.IsValid())
{
Expand All @@ -185,7 +185,7 @@ void ezAssetDocument::AddReferences(const ezDocumentObject* pObject, ezAssetDocu
pInfo->m_RuntimeDependencies.Insert(ezConversionUtils::ToString(pMeta->m_CreateFromPrefab, tmp));
}

m_DocumentObjectMetaData.EndReadMetaData();
m_DocumentObjectMetaData->EndReadMetaData();
}

const ezRTTI* pType = pObject->GetTypeAccessor().GetType();
Expand Down
17 changes: 14 additions & 3 deletions Code/Editor/EditorFramework/Document/GameObjectDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ class EZ_EDITORFRAMEWORK_DLL ezGameObjectDocument : public ezAssetDocument
ezAssetDocEngineConnection engineConnectionType = ezAssetDocEngineConnection::FullObjectMirroring);
~ezGameObjectDocument();


virtual ezEditorInputContext* GetEditorInputContextOverride() override;

protected:
void SubscribeGameObjectEventHandlers();
void UnsubscribeGameObjectEventHandlers();

/// \name Gizmo
///@{
public:
Expand Down Expand Up @@ -229,21 +234,21 @@ class EZ_EDITORFRAMEWORK_DLL ezGameObjectDocument : public ezAssetDocument

public:
mutable ezEvent<const ezGameObjectEvent&> m_GameObjectEvents;
mutable ezObjectMetaData<ezUuid, ezGameObjectMetaData> m_GameObjectMetaData;
mutable ezUniquePtr<ezObjectMetaData<ezUuid, ezGameObjectMetaData>> m_GameObjectMetaData;

static ezEvent<const ezGameObjectDocumentEvent&> s_GameObjectDocumentEvents;

protected:
void InvalidateGlobalTransformValue(const ezDocumentObject* pObject) const;
/// \brief Sends the current state of the scene to the engine process. This is typically done after scene load or when the world might have deviated
/// on the engine side (after play the game etc.)
void SendGameWorldToEngine();
virtual void SendGameWorldToEngine();

virtual void InitializeAfterLoading(bool bFirstTimeCreation) override;
virtual void AttachMetaDataBeforeSaving(ezAbstractObjectGraph& graph) const override;
virtual void RestoreMetaDataAfterLoading(const ezAbstractObjectGraph& graph, bool bUndoable) override;

private:
public:
void SelectionManagerEventHandler(const ezSelectionManagerEvent& e);
void ObjectPropertyEventHandler(const ezDocumentObjectPropertyEvent& e);
void ObjectStructureEventHandler(const ezDocumentObjectStructureEvent& e);
Expand Down Expand Up @@ -273,4 +278,10 @@ class EZ_EDITORFRAMEWORK_DLL ezGameObjectDocument : public ezAssetDocument
// therefore when the selection is changed in the first frame, it might not be fully correct
// by sending it a second time, we can fix that easily
ezInt8 m_iResendSelection = 0;

protected:
ezEventSubscriptionID m_SelectionManagerEventHandlerID;
ezEventSubscriptionID m_ObjectPropertyEventHandlerID;
ezEventSubscriptionID m_ObjectStructureEventHandlerID;
ezEventSubscriptionID m_ObjectEventHandlerID;
};
Loading

0 comments on commit 98809a4

Please sign in to comment.