1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "IEditorImpl.h"
6 #include "CryEditDoc.h"
7 #include "Dialogs/CustomColorDialog.h"
8 #include "ClassFactory.h"
9 #include <CryCore/ToolsHelpers/ResourceCompilerHelper.h>
11 #include "PluginManager.h"
12 #include "IconManager.h"
13 #include "ViewManager.h"
14 #include "Gizmos/GizmoManager.h"
15 #include "Gizmos/TransformManipulator.h"
16 #include "HyperGraph/FlowGraphManager.h"
17 #include "HyperGraph/FlowGraphModuleManager.h"
18 #include "HyperGraph/Controls/FlowGraphDebuggerEditor.h"
19 #include "Export/ExportManager.h"
20 #include "Material/MaterialFXGraphMan.h"
21 #include "CustomActions/CustomActionsEditorManager.h"
22 #include "AI/AIManager.h"
23 #include "UI/UIManager.h"
24 #include "Undo/Undo.h"
25 #include "Material/MaterialManager.h"
26 #include "Material/MaterialPickTool.h"
27 #include "EntityPrototypeManager.h"
28 #include "GameEngine.h"
29 #include "BaseLibraryDialog.h"
30 #include "Material/Material.h"
31 #include "EntityPrototype.h"
32 #include "Particles/ParticleManager.h"
33 #include "Prefabs/PrefabManager.h"
34 #include "GameTokens/GameTokenManager.h"
35 #include "LensFlareEditor/LensFlareManager.h"
36 #include "DataBaseDialog.h"
37 #include "UIEnumsDatabase.h"
38 #include "Util/Ruler.h"
39 #include "Script/ScriptEnvironment.h"
40 #include "Gizmos/AxisHelper.h"
41 #include "PickObjectTool.h"
42 #include "ObjectCreateTool.h"
43 #include "Vegetation/VegetationMap.h"
44 #include "Terrain/TerrainManager.h"
45 #include "Terrain/SurfaceType.h"
46 #include <Cry3DEngine/I3DEngine.h>
47 #include <CrySystem/IConsole.h>
48 #include <CryEntitySystem/IEntitySystem.h>
49 #include <CryMovie/IMovieSystem.h>
50 #include <ISourceControl.h>
51 #include <IDevManager.h>
52 #include "Objects/ObjectLayerManager.h"
53 #include "BackgroundTaskManager.h"
54 #include "BackgroundScheduleManager.h"
55 #include "EditorFileMonitor.h"
56 #include <CrySandbox/IEditorGame.h>
57 #include "EditMode/ObjectMode.h"
59 #include "Commands/PythonManager.h"
60 #include "Commands/PolledKeyManager.h"
61 #include "EditorFramework/PersonalizationManager.h"
62 #include "EditorFramework/BroadcastManager.h"
63 #include "LevelEditor/LevelEditorSharedState.h"
64 #include "EditorCommonInit.h"
65 #include "AssetSystem/AssetManager.h"
66 #include <Preferences/ViewportPreferences.h>
67 #include "MainThreadWorker.h"
69 #include <CrySerialization/Serializer.h>
70 #include <CrySandbox/CryInterop.h>
71 #include "ResourceSelectorHost.h"
72 #include "Util/BoostPythonHelpers.h"
74 #include "FileSystem/FileSystem_Enumerator.h"
76 #include "QT/QtMainFrame.h"
77 #include "QT/QToolTabManager.h"
78 #include "QT/Widgets/QPreviewWidget.h"
79 #include "Material/MaterialBrowser.h"
81 #include "Controls/QuestionDialog.h"
82 #include "FilePathUtil.h"
83 #include <Notifications/NotificationCenterImpl.h>
84 #include <EditorFramework/TrayArea.h>
85 #include <EditorFramework/Preferences.h>
86 #include <Preferences/GeneralPreferences.h>
87 #include <CrySystem/IProjectManager.h>
90 #include "ConfigurationManager.h"
91 #include <CryGame/IGameFramework.h>
93 LINK_SYSTEM_LIBRARY("version.lib")
94 // Shell utility library
95 LINK_SYSTEM_LIBRARY("Shlwapi.lib")
98 #include "SurfaceInfoPicker.h"
99 #include "Objects/PrefabObject.h"
100 #include "PhysTool.h"
102 #include "MFCToolsPlugin.h"
104 // even in Release mode, the editor will return its heap, because there's no Profile build configuration for the editor
108 #include <CryCore/CrtDebugStats.h>
109 #include "LinkTool.h"
111 static CCryEditDoc
* theDocument
;
112 static CEditorImpl
* s_pEditor
= NULL
;
114 IEditor
* GetIEditor() { return s_pEditor
; }
116 CEditorImpl
* GetIEditorImpl()
121 CEditorImpl::CEditorImpl(CGameEngine
* ge
)
122 : m_bInitialized(false)
123 , m_objectHideMask(0)
124 , editorConfigSpec(CONFIG_MEDIUM_SPEC
)
125 , m_areHelpersEnabled(true)
127 LOADING_TIME_PROFILE_SECTION
;
129 //This is dangerous and should (in theory) be set at the end of the constructor for safety, after everything is properly initialized.
130 //Code within this scope can use GetIEditorImpl() at their own risk
133 //init game engine first as there may be a lot of things depending on pSystem or gEnv.
134 m_pSystem
= ge
->GetSystem();
136 RegisterNotifyListener(m_pGameEngine
);
138 EditorCommon::SetIEditor(this);
139 MFCToolsPlugin::SetEditor(s_pEditor
);
141 m_currEditMode
= eEditModeSelect
;
142 m_prevEditMode
= m_currEditMode
;
144 m_pLevelIndependentFileMan
= new CLevelIndependentFileMan
;
145 m_pLevelEditorSharedState
.reset(new LevelEditorSharedState
);
146 m_pExportManager
= 0;
149 m_pClassFactory
= CClassFactory::Instance();
151 m_pGlobalBroadcastManager
= new CBroadcastManager();
152 m_pNotificationCenter
= new CNotificationCenter();
153 m_pTrayArea
= new CTrayArea();
154 m_pCommandManager
= new CEditorCommandManager();
155 m_pPersonalizationManager
= new CPersonalizationManager();
156 m_pPreferences
= new CPreferences();
157 CAutoRegisterPreferencesHelper::RegisterAll();
158 m_pPythonManager
= new CEditorPythonManager();
159 m_pPythonManager
->Init();//must be initialized before plugins are initialized
160 m_pAssetManager
= new CAssetManager();
161 m_pPolledKeyManager
= new CPolledKeyManager();
163 m_pEditorFileMonitor
.reset(new CEditorFileMonitor());
164 m_pBackgroundTaskManager
.reset(new BackgroundTaskManager::CTaskManager
);
165 m_pBackgroundScheduleManager
.reset(new BackgroundScheduleManager::CScheduleManager
);
166 m_pBGTasks
.reset(new BackgroundTaskManager::CBackgroundTasksListener
);
168 m_pUIEnumsDatabase
= new CUIEnumsDatabase
;
169 m_pPluginManager
= new CPluginManager
;
170 m_pTerrainManager
= new CTerrainManager();
171 m_pVegetationMap
= new CVegetationMap();
172 m_pObjectManager
= new CObjectManager
;
173 m_pGizmoManager
= new CGizmoManager
;
174 m_pViewManager
= new CViewManager
;
175 m_pIconManager
= new CIconManager
;
176 m_pUndoManager
= new CUndoManager
;
177 m_pAIManager
= new CAIManager
;
178 m_pUIManager
= new CUIManager
;
179 m_pCustomActionsManager
= new CCustomActionsEditorManager
;
180 m_pMaterialManager
= new CMaterialManager();
181 m_pEntityManager
= new CEntityPrototypeManager
;
182 m_particleManager
= new CParticleManager
;
183 m_pPrefabManager
= new CPrefabManager
;
184 m_pGameTokenManager
= new CGameTokenManager
;
185 m_pFlowGraphManager
= new CFlowGraphManager
;
187 m_pLensFlareManager
= new CLensFlareManager
;
188 m_pFlowGraphModuleManager
= new CEditorFlowGraphModuleManager
;
189 m_pFlowGraphDebuggerEditor
= new CFlowGraphDebuggerEditor
;
190 m_pMatFxGraphManager
= new CMaterialFXGraphMan
;
191 m_pDevManager
= new CDevManager();
192 m_pSourceControl
= 0;
193 m_pScriptEnv
= new EditorScriptEnvironment();
195 m_pResourceSelectorHost
.reset(CreateResourceSelectorHost());
196 CAutoRegisterResourceSelector::RegisterAll();
198 m_pRuler
= new CRuler
;
199 m_pConfigurationManager
= new CConfigurationManager();
201 m_pMainThreadWorker
= new CMainThreadWorker();
203 m_selectedRegion
.min
= Vec3(0, 0, 0);
204 m_selectedRegion
.max
= Vec3(0, 0, 0);
205 ZeroStruct(m_lastAxis
);
206 m_lastAxis
[eEditModeSelect
] = AXIS_XY
;
207 m_lastAxis
[eEditModeSelectArea
] = AXIS_XY
;
208 m_lastAxis
[eEditModeMove
] = AXIS_XY
;
209 m_lastAxis
[eEditModeRotate
] = AXIS_Z
;
210 m_lastAxis
[eEditModeScale
] = AXIS_XY
;
211 ZeroStruct(m_lastCoordSys
);
212 m_lastCoordSys
[eEditModeSelect
] = COORDS_LOCAL
;
213 m_lastCoordSys
[eEditModeSelectArea
] = COORDS_LOCAL
;
214 m_lastCoordSys
[eEditModeMove
] = COORDS_LOCAL
;
215 m_lastCoordSys
[eEditModeRotate
] = COORDS_LOCAL
;
216 m_lastCoordSys
[eEditModeScale
] = COORDS_LOCAL
;
217 m_bAxisVectorLock
= false;
220 m_bSelectionLocked
= false;
224 m_bMatEditMode
= false;
225 m_bShowStatusText
= true;
227 doc_use_subfolder_for_crash_backup
= 0;
229 CPhysPullTool::RegisterCVars();
231 MFCToolsPlugin::Initialize();
232 EditorCommon::Initialize();
234 m_pGameEngine
->InitAdditionalEngineComponents();
237 void CEditorImpl::Init()
239 m_pCommandManager
->RegisterAutoCommands();
243 gEnv
->pRenderer
->AddAsyncTextureCompileListener(m_pBGTasks
.get());
245 m_pSystem
->GetISystemEventDispatcher()->RegisterListener(this, "CEditorImpl");
247 gEnv
->pInput
->OnFilterInputEvent
= OnFilterInputEvent
;
249 CAutoRegisterClassHelper::RegisterAll();
251 m_pPolledKeyManager
->Init();
253 m_pBackgroundTaskManager
->AddListener(m_pBGTasks
.get(), "Editor");
255 auto projectPath
= PathUtil::GetGameProjectAssetsPath();
256 m_pFileSystemEnumerator
.reset(new FileSystem::CEnumerator(projectPath
.c_str()));
258 m_pNotificationCenter
->Init();
262 m_templateRegistry
.LoadTemplates("%EDITOR%");
264 m_pConfigurationManager
->Init();
267 CEditorImpl::~CEditorImpl()
269 m_pSystem
->GetISystemEventDispatcher()->RemoveListener(this);
270 m_bExiting
= true; // Can't save level after this point (while Crash)
271 SAFE_DELETE(m_pScriptEnv
);
272 SAFE_RELEASE(m_pSourceControl
);
273 SAFE_DELETE(m_pGameTokenManager
);
275 SAFE_DELETE(m_pMatFxGraphManager
);
276 SAFE_DELETE(m_pFlowGraphModuleManager
);
278 if (m_pFlowGraphDebuggerEditor
)
280 m_pFlowGraphDebuggerEditor
->Shutdown();
281 SAFE_DELETE(m_pFlowGraphDebuggerEditor
);
284 SAFE_DELETE(m_particleManager
)
285 SAFE_DELETE(m_pEntityManager
)
286 SAFE_DELETE(m_pMaterialManager
)
287 SAFE_DELETE(m_pIconManager
)
288 SAFE_DELETE(m_pViewManager
)
289 SAFE_DELETE(m_pObjectManager
) // relies on prefab manager
290 SAFE_DELETE(m_pPrefabManager
); // relies on flowgraphmanager
291 SAFE_DELETE(m_pGizmoManager
)
292 SAFE_DELETE(m_pFlowGraphManager
);
293 SAFE_DELETE(m_pVegetationMap
);
294 SAFE_DELETE(m_pTerrainManager
);
295 // AI should be destroyed after the object manager, as the objects may
296 // refer to AI components.
297 SAFE_DELETE(m_pAIManager
)
298 SAFE_DELETE(m_pUIManager
)
299 SAFE_DELETE(m_pCustomActionsManager
)
300 SAFE_DELETE(m_pPluginManager
)
301 SAFE_DELETE(m_pRuler
)
302 SAFE_DELETE(m_pPreferences
)
303 SAFE_DELETE(m_pPersonalizationManager
)
304 SAFE_DELETE(m_pCommandManager
)
305 SAFE_DELETE(m_pTrayArea
)
306 SAFE_DELETE(m_pNotificationCenter
)
307 SAFE_DELETE(m_pPythonManager
)
308 SAFE_DELETE(m_pPolledKeyManager
)
310 CAutoRegisterClassHelper::UnregisterAll();
311 SAFE_DELETE(m_pClassFactory
)
313 SAFE_DELETE(m_pUIEnumsDatabase
)
314 SAFE_DELETE(m_pExportManager
);
315 SAFE_DELETE(m_pDevManager
);
316 SAFE_DELETE(m_pConfigurationManager
);
317 // Game engine should be among the last things to be destroyed, as it
318 // destroys the engine.
319 SAFE_DELETE(m_pLevelIndependentFileMan
);
321 UnregisterNotifyListener(m_pGameEngine
);
322 SAFE_DELETE(m_pGameEngine
);
324 m_pGlobalBroadcastManager
->deleteLater();
326 EditorCommon::Deinitialize();
327 MFCToolsPlugin::Deinitialize();
331 bool CEditorImpl::IsMainFrameClosing() const
333 return CEditorMainFrame::GetInstance()->IsClosing();
336 void CEditorImpl::SetMasterCDFolder()
338 m_masterCDFolder
= wstring(L
".");
341 bool CEditorImpl::OnFilterInputEvent(SInputEvent
* pInput
)
343 CryInputEvent
event(pInput
);
344 event
.SendToKeyboardFocus();
345 return event
.isAccepted();
348 ILevelEditor
* CEditorImpl::GetLevelEditor()
350 return CEditorMainFrame::GetInstance()->GetLevelEditor();
353 void CEditorImpl::ExecuteCommand(const char* sCommand
, ...)
357 va_start(args
, sCommand
);
358 cry_vsprintf(buffer
, sCommand
, args
);
360 m_pCommandManager
->Execute(buffer
);
363 IPythonManager
* CEditorImpl::GetIPythonManager()
365 return m_pPythonManager
;
368 ICommandManager
* CEditorImpl::GetICommandManager()
370 return m_pCommandManager
;
373 void CEditorImpl::WriteToConsole(const char* pszString
)
375 CLogFile::WriteLine(pszString
);
378 const ISelectionGroup
* CEditorImpl::GetISelectionGroup() const
380 return GetSelection();
383 void CEditorImpl::Update()
388 // Make sure this is not called recursively
391 CRY_PROFILE_FUNCTION(PROFILE_EDITOR
);
394 //@FIXME: Restore this latter.
395 //if (GetGameEngine() && GetGameEngine()->IsLevelLoaded())
397 m_pObjectManager
->Update();
399 if (IsInPreviewMode())
401 SetModifiedFlag(FALSE
);
404 if (m_pGameEngine
!= NULL
)
406 IEditorGame
* pEditorGame
= m_pGameEngine
->GetIEditorGame();
407 if (pEditorGame
!= NULL
)
409 IEditorGame::HelpersDrawMode::EType helpersDrawMode
= IEditorGame::HelpersDrawMode::Hide
;
410 if (GetIEditor()->IsHelpersDisplayed())
412 helpersDrawMode
= IEditorGame::HelpersDrawMode::Show
;
414 pEditorGame
->UpdateHelpers(helpersDrawMode
);
418 for (EReloadScriptsType kind
: m_reloadScriptsQueue
)
423 case eReloadScriptsType_Actor
:
424 p
= ID_RELOAD_ACTOR_SCRIPTS
;
426 case eReloadScriptsType_AI
:
427 p
= ID_RELOAD_AI_SCRIPTS
;
429 case eReloadScriptsType_Entity
:
430 p
= ID_RELOAD_ENTITY_SCRIPTS
;
432 case eReloadScriptsType_Item
:
433 p
= ID_RELOAD_ITEM_SCRIPTS
;
435 case eReloadScriptsType_UI
:
436 p
= ID_RELOAD_UI_SCRIPTS
;
441 AfxGetMainWnd()->SendMessage(WM_COMMAND
, p
, 0);
443 m_reloadScriptsQueue
.clear();
448 ISystem
* CEditorImpl::GetSystem()
453 I3DEngine
* CEditorImpl::Get3DEngine()
456 return gEnv
->p3DEngine
;
460 IRenderer
* CEditorImpl::GetRenderer()
463 return gEnv
->pRenderer
;
467 IEditorClassFactory
* CEditorImpl::GetClassFactory()
469 return m_pClassFactory
;
472 CCryEditDoc
* CEditorImpl::GetDocument() const
477 void CEditorImpl::SetDocument(CCryEditDoc
* pDoc
)
482 void CEditorImpl::CloseDocument()
486 LOADING_TIME_PROFILE_SECTION
;
487 Notify(eNotify_OnBeginSceneClose
);
488 theDocument
->DeleteContents();
490 // might be better to just recreate an empty document instead to make sure no invalid access happens
491 theDocument
= nullptr;
492 Notify(eNotify_OnEndSceneClose
);
496 void CEditorImpl::SetModifiedFlag(bool modified
)
498 if (GetDocument() && GetDocument()->IsDocumentReady())
500 GetDocument()->SetModifiedFlag(modified
);
504 GetDocument()->SetLevelExported(false);
509 bool CEditorImpl::IsLevelExported() const
511 CCryEditDoc
* pDoc
= GetDocument();
515 return pDoc
->IsLevelExported();
521 bool CEditorImpl::SetLevelExported(bool boExported
)
525 GetDocument()->SetLevelExported(boExported
);
531 bool CEditorImpl::SaveDocument()
537 return GetDocument()->Save();
542 bool CEditorImpl::SaveDocumentBackup()
548 if (doc_use_subfolder_for_crash_backup
)
550 const CTime theTime
= CTime::GetCurrentTime();
551 const string backupFolder
= PathUtil::Make(PathUtil::GetUserSandboxFolder(), theTime
.Format("CrashBackup/%Y.%m.%d [%H-%M.%S]"));
552 GetAssetManager()->SaveBackup(backupFolder
);
556 GetAssetManager()->SaveAll(nullptr);
559 const char* const CRASH_FOLDER
= "/.CRASH_BACKUP/";
560 const char* const CRASH_FILE_PREFIX
= "CRASH_BACKUP_";
562 if (CCryEditDoc
* pDocument
= GetDocument())
564 bool bShouldCreateBackup
= true;
565 if (doc_use_subfolder_for_crash_backup
)
567 string sLevelFolder
= pDocument
->GetPathName().GetString(); // copy the string so we can modify it
568 if (sLevelFolder
.GetLength() != 0)
570 IObjectManager
* pObjectManager
= GetObjectManager();
576 CObjectLayerManager
* pObjectLayerManager
= pObjectManager
->GetLayersManager();
577 if (!pObjectLayerManager
)
582 string backupFolder
= sLevelFolder
.GetString(); // get the modifiable string buffer
583 backupFolder
= PathUtil::GetParentDirectory(backupFolder
);
584 backupFolder
.Append(CRASH_FOLDER
);
586 if (::CreateDirectory(backupFolder
, NULL
) || (GetLastError() == ERROR_ALREADY_EXISTS
))
588 string oldLayerPath
= pObjectLayerManager
->GetLayersPath();
589 string
newLayerPath(CRASH_FOLDER
);
590 newLayerPath
.Append(oldLayerPath
);
591 pObjectLayerManager
->SetLayersPath(newLayerPath
); // make sure layers are saved in the crash folder, not the current folder
592 string
fullLayerPath(backupFolder
);
593 fullLayerPath
.Append(oldLayerPath
);
594 if (::CreateDirectory(fullLayerPath
.GetString(), NULL
) || (GetLastError() == ERROR_ALREADY_EXISTS
))
596 string sLevelName
= pDocument
->GetPathName(); // copy the string so we can modify it
597 sLevelName
= PathUtil::GetFile(sLevelName
);
598 char szCrashBackupName
[MAX_PATH
];
599 cry_sprintf(szCrashBackupName
, "%s%s%s", backupFolder
.GetString(), CRASH_FILE_PREFIX
, sLevelName
.GetString());
601 pDocument
->SetPathName(szCrashBackupName
, false);
605 bShouldCreateBackup
= false;
608 pObjectLayerManager
->SetLayersPath(oldLayerPath
);
612 bShouldCreateBackup
= false;
617 if (bShouldCreateBackup
)
619 return pDocument
->Save();
626 string
CEditorImpl::GetMasterCDFolder()
628 return CryStringUtils::WStrToUTF8(m_masterCDFolder
.c_str());
631 string
CEditorImpl::GetLevelFolder()
633 return GetGameEngine()->GetLevelPath();
636 const char* CEditorImpl::GetLevelName()
638 m_levelNameBuffer
= GetGameEngine()->GetLevelName();
639 return m_levelNameBuffer
.GetBuffer();
642 const char* CEditorImpl::GetLevelPath()
644 return GetLevelFolder();
647 string
CEditorImpl::GetLevelDataFolder()
649 return PathUtil::AddSlash(PathUtil::Make(GetGameEngine()->GetLevelPath(), "LevelData")).c_str();
652 const char* CEditorImpl::GetUserFolder()
654 m_userFolder
= string(PathUtil::GetUserSandboxFolder().c_str());
658 void CEditorImpl::SetDataModified()
660 GetDocument()->SetModifiedFlag(TRUE
);
663 int CEditorImpl::GetEditMode()
665 return m_currEditMode
;
668 void CEditorImpl::SetEditMode(int editMode
)
670 m_currEditMode
= (EEditMode
)editMode
;
671 m_prevEditMode
= m_currEditMode
;
672 AABB
box(Vec3(0, 0, 0), Vec3(0, 0, 0));
673 SetSelectedRegion(box
);
675 if (GetEditTool() && !GetEditTool()->IsNeedMoveTool())
677 SetEditTool(0, true);
680 if (editMode
== eEditModeMove
|| editMode
== eEditModeRotate
|| editMode
== eEditModeScale
)
682 SetAxisConstrains(m_lastAxis
[editMode
]);
683 SetReferenceCoordSys(m_lastCoordSys
[editMode
]);
686 Notify(eNotify_OnEditModeChange
);
689 void CEditorImpl::SetEditTool(CEditTool
* tool
, bool bStopCurrentTool
)
691 CViewport
* pViewport
= GetIEditorImpl()->GetActiveView();
694 pViewport
->SetCurrentCursor(STD_CURSOR_DEFAULT
);
699 // Replace tool with the object modify edit tool.
700 if (m_pEditTool
!= 0 && m_pEditTool
->IsKindOf(RUNTIME_CLASS(CObjectMode
)))
707 tool
= new CObjectMode
;
711 Notify(eNotify_OnEditToolBeginChange
);
715 // Make sure pick is aborted.
716 if (tool
!= m_pPickTool
)
720 Notify(eNotify_OnEditToolEndChange
);
723 void CEditorImpl::SetEditTool(const string
& sEditToolName
, bool bStopCurrentTool
)
725 CEditTool
* pTool
= GetEditTool();
726 if (pTool
&& pTool
->GetRuntimeClass()->m_lpszClassName
)
728 // Check if already selected.
729 if (stricmp(pTool
->GetRuntimeClass()->m_lpszClassName
, sEditToolName
) == 0)
733 IClassDesc
* pClass
= GetIEditorImpl()->GetClassFactory()->FindClass(sEditToolName
);
736 Warning("Editor Tool %s not registered.", (const char*)sEditToolName
);
739 if (pClass
->SystemClassID() != ESYSTEM_CLASS_EDITTOOL
)
741 Warning("Class name %s is not a valid Edit Tool class.", (const char*)sEditToolName
);
744 CRuntimeClass
* pRtClass
= pClass
->GetRuntimeClass();
745 if (pRtClass
&& pRtClass
->IsDerivedFrom(RUNTIME_CLASS(CEditTool
)))
747 CEditTool
* pEditTool
= (CEditTool
*)pRtClass
->CreateObject();
748 GetIEditorImpl()->SetEditTool(pEditTool
);
753 Warning("Class name %s is not a valid Edit Tool class.", (const char*)sEditToolName
);
758 CEditTool
* CEditorImpl::GetEditTool()
763 void CEditorImpl::SetAxisConstrains(AxisConstrains axisFlags
)
765 gGizmoPreferences
.axisConstraint
= axisFlags
;
766 m_lastAxis
[m_currEditMode
] = gGizmoPreferences
.axisConstraint
;
767 m_pViewManager
->SetAxisConstrain(axisFlags
);
770 UpdateViews(eUpdateObjects
, NULL
);
771 Notify(eNotify_OnAxisConstraintChanged
);
774 AxisConstrains
CEditorImpl::GetAxisConstrains()
776 return gGizmoPreferences
.axisConstraint
;
779 uint16
CEditorImpl::GetSnapMode()
781 return m_snapModeFlags
;
784 void CEditorImpl::EnableSnapToTerrain(bool bEnable
)
786 m_snapModeFlags
&= ~eSnapMode_Terrain
;
787 if (bEnable
) // Disable geometry before enabling terrain snapping
788 m_snapModeFlags
= (m_snapModeFlags
& ~eSnapMode_Geometry
) | bEnable
* eSnapMode_Terrain
;
791 bool CEditorImpl::IsSnapToTerrainEnabled() const
793 return m_snapModeFlags
& eSnapMode_Terrain
;
796 void CEditorImpl::EnableSnapToNormal(bool bEnable
)
798 m_snapModeFlags
= (m_snapModeFlags
& ~eSnapMode_SurfaceNormal
) | bEnable
* eSnapMode_SurfaceNormal
;
801 void CEditorImpl::EnableHelpersDisplay(bool bEnable
)
803 m_areHelpersEnabled
= bEnable
;
806 void CEditorImpl::EnablePivotSnapping(bool bEnable
)
808 m_bPivotSnappingEnabled
= bEnable
;
811 bool CEditorImpl::IsSnapToNormalEnabled() const
813 return m_snapModeFlags
& eSnapMode_SurfaceNormal
;
816 bool CEditorImpl::IsHelpersDisplayed() const
818 return m_areHelpersEnabled
;
821 bool CEditorImpl::IsPivotSnappingEnabled() const
823 return m_bPivotSnappingEnabled
;
826 void CEditorImpl::EnableSnapToGeometry(bool bEnable
)
828 m_snapModeFlags
&= ~eSnapMode_Geometry
;
829 if (bEnable
) // Disable terrain before enabling geometry snapping
830 m_snapModeFlags
= (m_snapModeFlags
& ~eSnapMode_Terrain
) | bEnable
* eSnapMode_Geometry
;
833 bool CEditorImpl::IsSnapToGeometryEnabled() const
835 return m_snapModeFlags
& eSnapMode_Geometry
;
838 void CEditorImpl::SetReferenceCoordSys(RefCoordSys refCoords
)
840 if (refCoords
!= gGizmoPreferences
.referenceCoordSys
)
842 gGizmoPreferences
.referenceCoordSys
= refCoords
;
843 m_lastCoordSys
[m_currEditMode
] = gGizmoPreferences
.referenceCoordSys
;
846 UpdateViews(eUpdateObjects
, NULL
);
848 // Update the construction plane infos.
849 CViewport
* pViewport
= GetActiveView();
851 pViewport
->MakeSnappingGridPlane(GetIEditorImpl()->GetAxisConstrains());
853 Notify(eNotify_OnReferenceCoordSysChanged
);
857 RefCoordSys
CEditorImpl::GetReferenceCoordSys()
859 return gGizmoPreferences
.referenceCoordSys
;
862 CBaseObject
* CEditorImpl::NewObject(const char* type
, const char* file
/*=nullptr*/, bool bInteractive
/*= false*/)
864 CUndo
undo("Create new object");
866 CBaseObject
* pObject
= GetObjectManager()->NewObject(type
, 0, file
);
872 objectTM
.SetIdentity();
873 pObject
->SetLocalTM(objectTM
);
875 // if this object type was hidden by category, re-display it.
876 int hideMask
= gViewportDebugPreferences
.GetObjectHideMask();
877 hideMask
= hideMask
& ~(pObject
->GetType());
878 gViewportDebugPreferences
.SetObjectHideMask(hideMask
);
880 // Enable display of current layer.
881 CObjectLayer
* pLayer
= m_pObjectManager
->GetLayersManager()->GetCurrentLayer();
883 pLayer
->SetFrozen(false);
884 pLayer
->SetVisible(true);
885 pLayer
->SetModified();
887 m_pObjectManager
->ClearSelection();
888 m_pObjectManager
->SelectObject(pObject
);
900 //////////////////////////////////////////////////////////////////////////
901 void CEditorImpl::DeleteObject(CBaseObject
* obj
)
904 GetObjectManager()->DeleteObject(obj
);
907 CBaseObject
* CEditorImpl::CloneObject(CBaseObject
* obj
)
910 return GetObjectManager()->CloneObject(obj
);
913 void CEditorImpl::StartObjectCreation(const char* type
, const char* file
)
915 if (!GetDocument()->IsDocumentReady())
918 CObjectCreateTool
* tool
= new CObjectCreateTool();
919 GetIEditorImpl()->SetEditTool(tool
);
920 tool
->SelectObjectToCreate(type
, file
);
923 CBaseObject
* CEditorImpl::GetSelectedObject()
925 CBaseObject
* obj
= 0;
926 if (m_pObjectManager
->GetSelection()->GetCount() != 1)
928 return m_pObjectManager
->GetSelection()->GetObject(0);
931 void CEditorImpl::SelectObject(CBaseObject
* obj
)
933 GetObjectManager()->SelectObject(obj
);
936 void CEditorImpl::SelectObjects(std::vector
<CBaseObject
*> objects
)
938 GetObjectManager()->SelectObjects(objects
);
941 IObjectManager
* CEditorImpl::GetObjectManager()
943 return m_pObjectManager
;
946 IGizmoManager
* CEditorImpl::GetGizmoManager()
948 return m_pGizmoManager
;
951 const CSelectionGroup
* CEditorImpl::GetSelection() const
953 return m_pObjectManager
->GetSelection();
956 int CEditorImpl::ClearSelection()
958 if (GetSelection()->IsEmpty())
960 string countString
= GetCommandManager()->Execute("selection.clear");
962 FromString(count
, countString
.c_str());
966 void CEditorImpl::LockSelection(bool bLock
)
968 // Selection must be not empty to enable selection lock.
969 if (!GetSelection()->IsEmpty())
970 m_bSelectionLocked
= bLock
;
972 m_bSelectionLocked
= false;
975 bool CEditorImpl::IsSelectionLocked()
977 return m_bSelectionLocked
;
980 bool CEditorImpl::IsUpdateSuspended() const
982 return CCryEditApp::GetInstance()->IsUpdateSuspended();
985 bool CEditorImpl::IsGameInputSuspended()
987 return GetGameEngine()->IsGameInputSuspended();
990 void CEditorImpl::ToggleGameInputSuspended()
992 return GetGameEngine()->ToggleGameInputSuspended();
995 void CEditorImpl::PickObject(IPickObjectCallback
* callback
, CRuntimeClass
* targetClass
, bool bMultipick
)
997 m_pPickTool
= new CPickObjectTool(callback
, targetClass
);
998 ((CPickObjectTool
*)m_pPickTool
)->SetMultiplePicks(bMultipick
);
999 SetEditTool(m_pPickTool
);
1002 void CEditorImpl::CancelPick()
1008 bool CEditorImpl::IsPicking()
1010 if (GetEditTool() == m_pPickTool
&& m_pPickTool
!= 0)
1015 LevelEditorSharedState
* CEditorImpl::GetLevelEditorSharedState()
1017 return m_pLevelEditorSharedState
.get();
1020 CViewManager
* CEditorImpl::GetViewManager()
1022 return m_pViewManager
;
1025 IViewportManager
* CEditorImpl::GetViewportManager()
1027 return static_cast<IViewportManager
*>(GetViewManager());
1030 CViewport
* CEditorImpl::GetActiveView()
1032 return GetViewManager()->GetActiveViewport();
1035 IDisplayViewport
* CEditorImpl::GetActiveDisplayViewport()
1037 return GetViewManager()->GetActiveViewport();
1040 void CEditorImpl::SetActiveView(CViewport
* viewport
)
1042 m_pViewManager
->SelectViewport(viewport
);
1045 void CEditorImpl::UpdateViews(int flags
, AABB
* updateRegion
)
1047 AABB prevRegion
= m_pViewManager
->GetUpdateRegion();
1049 m_pViewManager
->SetUpdateRegion(*updateRegion
);
1050 m_pViewManager
->UpdateViews(flags
);
1052 m_pViewManager
->SetUpdateRegion(prevRegion
);
1055 void CEditorImpl::UpdateSequencer(bool bOnlyKeys
)
1058 Notify(eNotify_OnUpdateSequencerKeys
);
1060 Notify(eNotify_OnUpdateSequencer
);
1063 void CEditorImpl::ResetViews()
1065 m_pViewManager
->ResetViews();
1068 IIconManager
* CEditorImpl::GetIconManager()
1070 return m_pIconManager
;
1073 IBackgroundTaskManager
* CEditorImpl::GetBackgroundTaskManager()
1075 return m_pBackgroundTaskManager
.get();
1078 IBackgroundScheduleManager
* CEditorImpl::GetBackgroundScheduleManager()
1080 return m_pBackgroundScheduleManager
.get();
1083 IBackgroundTaskManagerListener
* CEditorImpl::GetIBackgroundTaskManagerListener()
1085 return m_pBGTasks
.get();
1088 IFileChangeMonitor
* CEditorImpl::GetFileMonitor()
1090 return m_pEditorFileMonitor
.get();
1093 float CEditorImpl::GetTerrainElevation(float x
, float y
)
1095 I3DEngine
* engine
= m_pSystem
->GetI3DEngine();
1098 return engine
->GetTerrainElevation(x
, y
);
1101 Vec3
CEditorImpl::GetTerrainNormal(const Vec3
& pos
)
1103 I3DEngine
* pEngine
= m_pSystem
->GetI3DEngine();
1107 return pEngine
->GetTerrainSurfaceNormal(pos
);
1110 CHeightmap
* CEditorImpl::GetHeightmap()
1112 assert(m_pTerrainManager
);
1113 return m_pTerrainManager
->GetHeightmap();
1116 CVegetationMap
* CEditorImpl::GetVegetationMap()
1118 return m_pVegetationMap
;
1121 void CEditorImpl::SetSelectedRegion(const AABB
& box
)
1123 m_selectedRegion
= box
;
1126 void CEditorImpl::GetSelectedRegion(AABB
& box
)
1128 box
= m_selectedRegion
;
1131 CWnd
* CEditorImpl::OpenView(const char* sViewClassName
)
1133 return CTabPaneManager::GetInstance()->OpenMFCPane(sViewClassName
);
1136 CWnd
* CEditorImpl::FindView(const char* sViewClassName
)
1138 return CTabPaneManager::GetInstance()->FindMFCPane(sViewClassName
);
1141 IPane
* CEditorImpl::CreateDockable(const char* className
)
1143 return CTabPaneManager::GetInstance()->CreatePane(className
);
1146 void CEditorImpl::RaiseDockable(IPane
* pPane
)
1148 CTabPaneManager::GetInstance()->BringToFront(pPane
);
1151 QWidget
* CEditorImpl::CreatePreviewWidget(const QString
& file
, QWidget
* pParent
)
1153 const static QStringList validGeometryExtensions
= []()
1156 result
<< QStringLiteral(CRY_SKEL_FILE_EXT
)
1157 << QStringLiteral(CRY_SKIN_FILE_EXT
)
1158 << QStringLiteral(CRY_CHARACTER_DEFINITION_FILE_EXT
)
1159 << QStringLiteral(CRY_ANIM_GEOMETRY_FILE_EXT
)
1160 << QStringLiteral(CRY_GEOMETRY_FILE_EXT
);
1164 const QFileInfo
info(file
);
1165 if (validGeometryExtensions
.contains(info
.suffix()))
1167 return new QPreviewWidget(file
, pParent
);
1169 else if (info
.suffix() == CRY_MATERIAL_FILE_EXT
)
1171 return new QMaterialPreview(file
, pParent
);
1173 else if (info
.suffix() == "dds")
1175 return new QTexturePreview(file
, pParent
);
1181 void CEditorImpl::PostOnMainThread(std::function
<void()> task
)
1185 CMainThreadWorker::GetInstance().AddTask(std::move(task
));
1189 IDataBaseManager
* CEditorImpl::GetDBItemManager(EDataBaseItemType itemType
)
1193 case EDB_TYPE_MATERIAL
:
1194 return m_pMaterialManager
;
1195 case EDB_TYPE_ENTITY_ARCHETYPE
:
1196 return m_pEntityManager
;
1197 case EDB_TYPE_PREFAB
:
1198 return m_pPrefabManager
;
1199 case EDB_TYPE_GAMETOKEN
:
1200 return m_pGameTokenManager
;
1201 case EDB_TYPE_PARTICLE
:
1202 return m_particleManager
;
1207 CBaseLibraryDialog
* CEditorImpl::OpenDataBaseLibrary(EDataBaseItemType type
, IDataBaseItem
* pItem
)
1210 type
= pItem
->GetType();
1213 if (type
== EDB_TYPE_MATERIAL
)
1215 pWnd
= OpenView("Material Editor Legacy");
1219 pWnd
= OpenView("DataBase View");
1222 IDataBaseManager
* pManager
= GetDBItemManager(type
);
1224 pManager
->SetSelectedItem(pItem
);
1226 if (pWnd
&& pWnd
->IsKindOf(RUNTIME_CLASS(CBaseLibraryDialog
)))
1228 return (CBaseLibraryDialog
*)pWnd
;
1230 if (pWnd
&& pWnd
->IsKindOf(RUNTIME_CLASS(CDataBaseDialog
)))
1232 CDataBaseDialog
* dlgDB
= (CDataBaseDialog
*)pWnd
;
1233 CDataBaseDialogPage
* pPage
= dlgDB
->SelectDialog(type
, pItem
);
1234 if (pPage
&& pPage
->IsKindOf(RUNTIME_CLASS(CBaseLibraryDialog
)))
1236 return (CBaseLibraryDialog
*)pPage
;
1242 bool CEditorImpl::SelectColor(COLORREF
& color
, CWnd
* parent
)
1244 COLORREF col
= color
;
1245 CCustomColorDialog
dlg(col
, CC_FULLOPEN
, parent
);
1246 if (dlg
.DoModal() == IDOK
)
1248 color
= dlg
.GetColor();
1254 void CEditorImpl::SetInGameMode(bool inGame
)
1256 static bool bWasInSimulationMode(false);
1260 bWasInSimulationMode
= GetIEditorImpl()->GetGameEngine()->GetSimulationMode();
1261 GetIEditorImpl()->GetGameEngine()->SetSimulationMode(false);
1262 GetIEditorImpl()->GetCommandManager()->Execute("game.enter");
1266 GetIEditorImpl()->GetCommandManager()->Execute("game.exit");
1267 GetIEditorImpl()->GetGameEngine()->SetSimulationMode(bWasInSimulationMode
);
1271 bool CEditorImpl::IsInGameMode()
1274 return m_pGameEngine
->IsInGameMode();
1278 bool CEditorImpl::IsInTestMode()
1280 return CCryEditApp::GetInstance()->IsInTestMode();
1283 bool CEditorImpl::IsInConsolewMode()
1285 return CCryEditApp::GetInstance()->IsInConsoleMode();
1288 bool CEditorImpl::IsInLevelLoadTestMode()
1290 return CCryEditApp::GetInstance()->IsInLevelLoadTestMode();
1293 bool CEditorImpl::IsInPreviewMode()
1295 return CCryEditApp::GetInstance()->IsInPreviewMode();
1298 void CEditorImpl::EnableAcceleratos(bool bEnable
)
1300 m_pCommandManager
->SetEditorUIActionsEnabled(bEnable
);
1303 void CEditorImpl::DetectVersion()
1305 char exe
[_MAX_PATH
];
1311 GetModuleFileName(NULL
, exe
, _MAX_PATH
);
1313 int verSize
= GetFileVersionInfoSize(exe
, &dwHandle
);
1316 GetFileVersionInfo(exe
, dwHandle
, 1024 * 8, ver
);
1317 VS_FIXEDFILEINFO
* vinfo
;
1318 VerQueryValue(ver
, "\\", (void**)&vinfo
, &len
);
1320 m_fileVersion
.v
[0] = vinfo
->dwFileVersionLS
& 0xFFFF;
1321 m_fileVersion
.v
[1] = vinfo
->dwFileVersionLS
>> 16;
1322 m_fileVersion
.v
[2] = vinfo
->dwFileVersionMS
& 0xFFFF;
1323 m_fileVersion
.v
[3] = vinfo
->dwFileVersionMS
>> 16;
1325 m_productVersion
.v
[0] = vinfo
->dwProductVersionLS
& 0xFFFF;
1326 m_productVersion
.v
[1] = vinfo
->dwProductVersionLS
>> 16;
1327 m_productVersion
.v
[2] = vinfo
->dwProductVersionMS
& 0xFFFF;
1328 m_productVersion
.v
[3] = vinfo
->dwProductVersionMS
>> 16;
1332 XmlNodeRef
CEditorImpl::FindTemplate(const string
& templateName
)
1334 return m_templateRegistry
.FindTemplate(templateName
);
1337 void CEditorImpl::AddTemplate(const string
& templateName
, XmlNodeRef
& tmpl
)
1339 m_templateRegistry
.AddTemplate(templateName
, tmpl
);
1342 void CEditorImpl::OpenAndFocusDataBase(EDataBaseItemType type
, IDataBaseItem
* pItem
)
1344 OpenDataBaseLibrary(type
, pItem
);
1347 void CEditorImpl::SetConsoleVar(const char* var
, float value
)
1349 ICVar
* ivar
= GetSystem()->GetIConsole()->GetCVar(var
);
1354 void CEditorImpl::SetConsoleStringVar(const char* var
, const char* value
)
1356 ICVar
* ivar
= GetSystem()->GetIConsole()->GetCVar(var
);
1361 float CEditorImpl::GetConsoleVar(const char* var
)
1363 ICVar
* ivar
= GetSystem()->GetIConsole()->GetCVar(var
);
1366 return ivar
->GetFVal();
1371 IAIManager
* CEditorImpl::GetAIManager()
1373 return m_pAIManager
;
1376 CCustomActionsEditorManager
* CEditorImpl::GetCustomActionManager()
1378 return m_pCustomActionsManager
;
1381 void CEditorImpl::OnObjectHideMaskChanged()
1383 int hideMask
= gViewportDebugPreferences
.GetObjectHideMask();
1384 int maskChanges
= m_objectHideMask
^ hideMask
;
1386 if (maskChanges
& (OBJTYPE_ENTITY
| OBJTYPE_PREFAB
| OBJTYPE_GROUP
| OBJTYPE_BRUSH
| OBJTYPE_GEOMCACHE
))
1387 gEnv
->p3DEngine
->OnObjectModified(NULL
, ERF_CASTSHADOWMAPS
);
1389 GetIEditorImpl()->Notify(eNotify_OnDisplayRenderUpdate
);
1391 m_objectHideMask
= hideMask
;
1394 void CEditorImpl::Notify(EEditorNotifyEvent event
)
1399 std::list
<IEditorNotifyListener
*>::iterator it
= m_listeners
.begin();
1400 while (it
!= m_listeners
.end())
1402 (*it
++)->OnEditorNotifyEvent(event
);
1406 void CEditorImpl::RegisterNotifyListener(IEditorNotifyListener
* listener
)
1408 listener
->m_bIsRegistered
= true;
1409 stl::push_back_unique(m_listeners
, listener
);
1412 void CEditorImpl::UnregisterNotifyListener(IEditorNotifyListener
* listener
)
1414 m_listeners
.remove(listener
);
1415 listener
->m_bIsRegistered
= false;
1418 ISourceControl
* CEditorImpl::GetSourceControl()
1420 if (!gEditorGeneralPreferences
.enableSourceControl())
1423 if (m_pSourceControl
)
1424 return m_pSourceControl
;
1426 std::vector
<IClassDesc
*> classes
;
1427 GetIEditorImpl()->GetClassFactory()->GetClassesBySystemID(ESYSTEM_CLASS_SCM_PROVIDER
, classes
);
1428 for (int i
= 0; i
< classes
.size(); i
++)
1430 IClassDesc
* pClass
= classes
[i
];
1431 ISourceControl
* pSCM
= (ISourceControl
*)pClass
;
1434 m_pSourceControl
= pSCM
;
1435 return m_pSourceControl
;
1442 IProjectManager
* CEditorImpl::GetProjectManager()
1444 return m_pSystem
->GetIProjectManager();
1447 bool CEditorImpl::IsSourceControlAvailable()
1449 if (gEditorGeneralPreferences
.enableSourceControl() && GetSourceControl())
1455 void CEditorImpl::SetMatEditMode(bool bIsMatEditMode
)
1457 m_bMatEditMode
= bIsMatEditMode
;
1460 void CEditorImpl::ShowStatusText(bool bEnable
)
1462 m_bShowStatusText
= bEnable
;
1465 FileSystem::CEnumerator
* CEditorImpl::GetFileSystemEnumerator()
1467 return m_pFileSystemEnumerator
.get();
1470 void CEditorImpl::GetMemoryUsage(ICrySizer
* pSizer
)
1472 SIZER_COMPONENT_NAME(pSizer
, "Editor");
1476 SIZER_COMPONENT_NAME(pSizer
, "Document");
1478 GetDocument()->GetMemoryUsage(pSizer
);
1481 if (m_pVegetationMap
)
1482 m_pVegetationMap
->GetMemoryUsage(pSizer
);
1485 void CEditorImpl::ReduceMemory()
1487 GetIEditorImpl()->GetIUndoManager()->ClearRedoStack();
1488 GetIEditorImpl()->GetIUndoManager()->ClearUndoStack();
1489 GetIEditorImpl()->GetObjectManager()->SendEvent(EVENT_FREE_GAME_DATA
);
1491 HANDLE hHeap
= GetProcessHeap();
1495 uint64 maxsize
= (uint64
)HeapCompact(hHeap
, 0);
1496 CryLogAlways("Max Free Memory Block = %I64d Kb", maxsize
/ 1024);
1500 IExportManager
* CEditorImpl::GetExportManager()
1502 if (!m_pExportManager
)
1503 m_pExportManager
= new CExportManager();
1505 return m_pExportManager
;
1508 void CEditorImpl::AddUIEnums()
1510 // Spec settings for shadow casting lights
1511 string SpecString
[4];
1512 std::vector
<string
> types
;
1513 types
.push_back("Never=0");
1514 SpecString
[0].Format("VeryHigh Spec=%d", CONFIG_VERYHIGH_SPEC
);
1515 types
.push_back(SpecString
[0].c_str());
1516 SpecString
[1].Format("High Spec=%d", CONFIG_HIGH_SPEC
);
1517 types
.push_back(SpecString
[1].c_str());
1518 SpecString
[2].Format("Medium Spec=%d", CONFIG_MEDIUM_SPEC
);
1519 types
.push_back(SpecString
[2].c_str());
1520 SpecString
[3].Format("Low Spec=%d", CONFIG_LOW_SPEC
);
1521 types
.push_back(SpecString
[3].c_str());
1522 m_pUIEnumsDatabase
->SetEnumStrings("CastShadows", types
);
1524 // Power-of-two percentages
1525 string percentStringPOT
[5];
1527 percentStringPOT
[0].Format("Default=%d", 0);
1528 types
.push_back(percentStringPOT
[0].c_str());
1529 percentStringPOT
[1].Format("12.5=%d", 1);
1530 types
.push_back(percentStringPOT
[1].c_str());
1531 percentStringPOT
[2].Format("25=%d", 2);
1532 types
.push_back(percentStringPOT
[2].c_str());
1533 percentStringPOT
[3].Format("50=%d", 3);
1534 types
.push_back(percentStringPOT
[3].c_str());
1535 percentStringPOT
[4].Format("100=%d", 4);
1536 types
.push_back(percentStringPOT
[4].c_str());
1537 m_pUIEnumsDatabase
->SetEnumStrings("ShadowMinResPercent", types
);
1540 void CEditorImpl::SetEditorConfigSpec(ESystemConfigSpec spec
)
1542 editorConfigSpec
= spec
;
1543 if (m_pSystem
->GetConfigSpec(true) != spec
)
1545 m_pSystem
->SetConfigSpec(spec
, true);
1546 editorConfigSpec
= m_pSystem
->GetConfigSpec(true);
1547 GetObjectManager()->SendEvent(EVENT_CONFIG_SPEC_CHANGE
);
1548 if (m_pVegetationMap
)
1549 m_pVegetationMap
->UpdateConfigSpec();
1550 Notify(eNotify_EditorConfigSpecChanged
);
1552 SET_PERSONALIZATION_PROPERTY(CEditorImpl
, "configSpec", editorConfigSpec
);
1555 ESystemConfigSpec
CEditorImpl::GetEditorConfigSpec() const
1557 return editorConfigSpec
;
1560 void CEditorImpl::InitFinished()
1562 LOADING_TIME_PROFILE_SECTION
;
1564 if (!m_bInitialized
)
1566 m_bInitialized
= true;
1567 Notify(eNotify_OnInit
);
1569 REGISTER_CVAR(doc_use_subfolder_for_crash_backup
, 0, VF_NULL
, "When saving a level after the editor has crashed, save to a sub-folder instead of overwriting the level");
1570 REGISTER_COMMAND("py", CmdPy
, 0, "Execute a Python code snippet.");
1572 // Let system wide listeners know about this as well.
1573 GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_EDITOR_ON_INIT
, 0, 0);
1575 if (m_pPersonalizationManager
->HasProperty("CEditorImpl", "configSpec"))
1576 editorConfigSpec
= (ESystemConfigSpec
)GET_PERSONALIZATION_PROPERTY(CEditorImpl
, "configSpec").toInt();
1577 SetEditorConfigSpec(editorConfigSpec
);
1579 m_pNotificationCenter
->Init();
1580 m_pPreferences
->Init();
1581 SEditorSettings::Load();
1582 gViewportDebugPreferences
.objectHideMaskChanged
.Connect(this, &CEditorImpl::OnObjectHideMaskChanged
);
1583 m_pObjectManager
->LoadClassTemplates("%EDITOR%");
1587 void CEditorImpl::ReloadTemplates()
1589 m_templateRegistry
.LoadTemplates("%EDITOR%");
1592 void CEditorImpl::CmdPy(IConsoleCmdArgs
* pArgs
)
1594 // Execute the given script command.
1595 string scriptCmd
= pArgs
->GetCommandLine();
1597 scriptCmd
= scriptCmd
.Right(scriptCmd
.GetLength() - 2); // The part of the text after the 'py'
1598 scriptCmd
= scriptCmd
.Trim();
1599 PyRun_SimpleString(scriptCmd
.GetString());
1603 void CEditorImpl::OnObjectContextMenuOpened(CPopupMenuItem
* pMenu
, const CBaseObject
* pObject
)
1605 for (auto iter
= m_objectContextMenuExtensions
.begin(); iter
!= m_objectContextMenuExtensions
.end(); ++iter
)
1607 (*iter
)(pMenu
, pObject
);
1611 void CEditorImpl::RegisterObjectContextMenuExtension(TContextMenuExtensionFunc func
)
1613 m_objectContextMenuExtensions
.push_back(func
);
1616 void CEditorImpl::SetCurrentMissionTime(float time
)
1618 if (CMission
* pMission
= GetIEditorImpl()->GetDocument()->GetCurrentMission())
1619 pMission
->SetTime(time
);
1622 float CEditorImpl::GetCurrentMissionTime()
1624 if (CMission
* pMission
= GetIEditorImpl()->GetDocument()->GetCurrentMission())
1625 return pMission
->GetTime();
1626 return 12.0f
; // return default value noon as 12 hours
1629 void CEditorImpl::OnSystemEvent(ESystemEvent event
, UINT_PTR wparam
, UINT_PTR lparam
)
1631 if (event
== ESYSTEM_EVENT_URI
)
1633 CCryURI
uri((const char*)wparam
);
1634 string uriSchema
= uri
.GetSchema();
1636 TURIListeners::iterator it
= m_uriListeners
.find(uriSchema
);
1637 if (it
!= m_uriListeners
.end())
1639 for (CListenerSet
<IUriEventListener
*>::Notifier
notifier(it
->second
); notifier
.IsValid(); notifier
.Next())
1641 notifier
->OnUriReceived(uri
.GetUri());
1647 void CEditorImpl::RegisterURIListener(IUriEventListener
* pListener
, const char* szSchema
)
1649 TURIListeners::iterator it
= m_uriListeners
.find(szSchema
);
1650 if (it
!= m_uriListeners
.end())
1652 it
->second
.Add(pListener
);
1656 string schamaName
= szSchema
;
1657 CListenerSet
<IUriEventListener
*> uriListener(4);
1658 uriListener
.Add(pListener
);
1659 m_uriListeners
.insert(std::make_pair(schamaName
, uriListener
));
1663 void CEditorImpl::UnregisterURIListener(IUriEventListener
* pListener
, const char* szSchema
)
1665 TURIListeners::iterator it
= m_uriListeners
.find(szSchema
);
1666 if (it
!= m_uriListeners
.end())
1668 if (it
->second
.Contains(pListener
))
1670 it
->second
.Remove(pListener
);
1674 void CEditorImpl::RequestScriptReload(const EReloadScriptsType
& kind
)
1676 m_reloadScriptsQueue
.insert(kind
);
1678 void CEditorImpl::AddNativeHandler(uintptr_t id
, std::function
<bool(void*, long*)> callback
)
1680 CEditorMainFrame::GetInstance()->m_loopHandler
.AddNativeHandler(id
, callback
);
1683 void CEditorImpl::RemoveNativeHandler(uintptr_t id
)
1685 CEditorMainFrame::GetInstance()->m_loopHandler
.RemoveNativeHandler(id
);
1687 //////////////////////////////////////////////////////////////////////////
1689 bool CEditorImpl::IsDocumentReady() const
1691 return GetDocument()->IsDocumentReady();
1694 void CEditorImpl::RemoveMemberCGroup(CBaseObject
* pGroup
, CBaseObject
* pObject
)
1696 CRY_ASSERT(IsCGroup(pGroup
));
1698 //Take a faster code path when closing
1699 bool bIsClosing
= m_bExiting
|| GetIEditor()->GetDocument()->IsClosing();
1701 ((CGroup
*)pGroup
)->RemoveMember(pObject
, !bIsClosing
, !bIsClosing
);
1704 bool CEditorImpl::IsCGroup(CBaseObject
* pObject
)
1706 return pObject
->IsKindOf(RUNTIME_CLASS(CGroup
));
1709 bool CEditorImpl::IsCPrefabObject(CBaseObject
* pObject
)
1711 return pObject
->IsKindOf(RUNTIME_CLASS(CPrefabObject
));
1714 void CEditorImpl::RegisterEntity(IRenderNode
* pRenderNode
)
1716 Get3DEngine()->RegisterEntity(pRenderNode
);
1719 void CEditorImpl::UnRegisterEntityAsJob(IRenderNode
* pRenderNode
)
1721 GetIEditorImpl()->Get3DEngine()->UnRegisterEntityAsJob(pRenderNode
);
1724 void CEditorImpl::SyncPrefabCPrefabObject(CBaseObject
* pObject
, const SObjectChangedContext
& context
)
1726 ((CPrefabObject
*)pObject
)->SyncPrefab(context
);
1729 bool CEditorImpl::IsModifyInProgressCPrefabObject(CBaseObject
* pObject
)
1731 return ((CPrefabObject
*)pObject
)->IsModifyInProgress();
1734 bool CEditorImpl::IsGroupOpen(CBaseObject
* pObject
)
1736 CGroup
* pGroup
= (CGroup
*)pObject
;
1737 return pGroup
->IsOpen();
1740 void CEditorImpl::OpenGroup(CBaseObject
* pObject
)
1742 if (!pObject
|| !IsCGroup(pObject
))
1745 CGroup
* pGroup
= static_cast<CGroup
*>(pObject
);
1746 if (!pGroup
->IsOpen())
1750 void CEditorImpl::ResumeUpdateCGroup(CBaseObject
* pObject
)
1752 ((CGroup
*)pObject
)->ResumeUpdate();
1755 bool CEditorImpl::SuspendUpdateCGroup(CBaseObject
* pObject
)
1757 return ((CGroup
*)pObject
)->SuspendUpdate();
1760 IEditorMaterial
* CEditorImpl::LoadMaterial(const string
& name
)
1762 if (GetMaterialManager())
1763 return GetMaterialManager()->LoadMaterial(name
);
1767 void CEditorImpl::OnRequestMaterial(IMaterial
* pMatInfo
)
1769 if (GetMaterialManager())
1770 GetMaterialManager()->OnRequestMaterial(pMatInfo
);
1773 void CEditorImpl::OnPrefabMake()
1775 m_pPrefabManager
->MakeFromSelection();
1778 bool CEditorImpl::PickObject(const Vec3
& vWorldRaySrc
, const Vec3
& vWorldRayDir
, SRayHitInfo
& outHitInfo
, CBaseObject
* pObject
)
1780 CSurfaceInfoPicker picker
;
1781 return picker
.PickObject(vWorldRaySrc
, vWorldRayDir
, outHitInfo
, pObject
);
1784 void CEditorImpl::AddWaitProgress(CWaitProgress
* pProgress
)
1786 if (CEditorMainFrame::GetInstance())
1787 CEditorMainFrame::GetInstance()->AddWaitProgress(pProgress
);
1790 void CEditorImpl::RemoveWaitProgress(CWaitProgress
* pProgress
)
1792 if (CEditorMainFrame::GetInstance())
1793 CEditorMainFrame::GetInstance()->AddWaitProgress(pProgress
);
1796 void CEditorImpl::RegisterDeprecatedPropertyEditor(int propertyType
, std::function
<bool(const string
&, string
&)>& handler
)
1798 m_deprecatedPropertyEditors
[propertyType
] = handler
;
1801 bool CEditorImpl::EditDeprecatedProperty(int propertyType
, const string
& oldValue
, string
& newValueOut
)
1803 auto handler
= m_deprecatedPropertyEditors
[propertyType
];
1806 return handler(oldValue
, newValueOut
);
1811 bool CEditorImpl::CanEditDeprecatedProperty(int propertyType
)
1813 auto handler
= m_deprecatedPropertyEditors
[propertyType
];
1820 bool CEditorImpl::ScanDirectory(const string
& path
, const string
& fileSpec
, std::vector
<string
>& filesOut
, bool recursive
/*= true*/)
1822 CFileUtil::FileArray result
;
1823 bool res
= CFileUtil::ScanDirectory(CString(path
), fileSpec
, result
, recursive
);
1824 if (res
&& !result
.empty())
1826 for (auto& file
: result
)
1828 filesOut
.push_back(file
.filename
.GetBuffer());
1834 void CEditorImpl::SetPlayerViewMatrix(const Matrix34
& tm
, bool bEyePos
/*= true*/)
1836 if (GetGameEngine())
1837 GetGameEngine()->SetPlayerViewMatrix(tm
, bEyePos
);