Explorar o código

Some refactoring

Panagiotis Christopoulos Charitos %!s(int64=3) %!d(string=hai) anos
pai
achega
e722dc1979
Modificáronse 59 ficheiros con 309 adicións e 361 borrados
  1. 27 8
      AnKi/Core/App.cpp
  2. 13 0
      AnKi/Resource/Common.h
  3. 3 2
      AnKi/Resource/CpuMeshResource.cpp
  4. 5 5
      AnKi/Resource/ImageResource.cpp
  5. 1 1
      AnKi/Resource/MaterialResource.cpp
  6. 1 6
      AnKi/Resource/MeshBinaryLoader.cpp
  7. 4 6
      AnKi/Resource/MeshBinaryLoader.h
  8. 17 17
      AnKi/Resource/MeshResource.cpp
  9. 4 8
      AnKi/Resource/ResourceManager.cpp
  10. 3 41
      AnKi/Resource/ResourceManager.h
  11. 4 4
      AnKi/Resource/ResourceObject.cpp
  12. 11 8
      AnKi/Resource/ResourceObject.h
  13. 2 2
      AnKi/Resource/ShaderProgramResource.cpp
  14. 12 12
      AnKi/Scene/CameraNode.cpp
  15. 27 0
      AnKi/Scene/Common.h
  16. 3 3
      AnKi/Scene/Components/BodyComponent.cpp
  17. 2 2
      AnKi/Scene/Components/DecalComponent.cpp
  18. 1 1
      AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp
  19. 8 8
      AnKi/Scene/Components/GpuParticleEmitterComponent.cpp
  20. 2 2
      AnKi/Scene/Components/JointComponent.cpp
  21. 1 1
      AnKi/Scene/Components/LensFlareComponent.cpp
  22. 3 2
      AnKi/Scene/Components/LightComponent.cpp
  23. 1 1
      AnKi/Scene/Components/ModelComponent.cpp
  24. 7 6
      AnKi/Scene/Components/ParticleEmitterComponent.cpp
  25. 1 1
      AnKi/Scene/Components/PlayerControllerComponent.cpp
  26. 1 1
      AnKi/Scene/Components/ReflectionProbeComponent.cpp
  27. 6 0
      AnKi/Scene/Components/SceneComponent.cpp
  28. 3 0
      AnKi/Scene/Components/SceneComponent.h
  29. 2 2
      AnKi/Scene/Components/ScriptComponent.cpp
  30. 1 1
      AnKi/Scene/Components/SkinComponent.cpp
  31. 1 1
      AnKi/Scene/Components/SkyboxComponent.cpp
  32. 2 2
      AnKi/Scene/Components/TriggerComponent.cpp
  33. 3 3
      AnKi/Scene/DebugDrawer.cpp
  34. 1 1
      AnKi/Scene/DebugDrawer.h
  35. 1 1
      AnKi/Scene/Events/AnimationEvent.cpp
  36. 7 2
      AnKi/Scene/Events/Event.cpp
  37. 2 0
      AnKi/Scene/Events/Event.h
  38. 2 2
      AnKi/Scene/Events/ScriptEvent.cpp
  39. 4 2
      AnKi/Scene/GlobalIlluminationProbeNode.cpp
  40. 3 3
      AnKi/Scene/ModelNode.cpp
  41. 1 1
      AnKi/Scene/PhysicsDebugNode.cpp
  42. 2 2
      AnKi/Scene/PlayerNode.cpp
  43. 4 2
      AnKi/Scene/ReflectionProbeNode.cpp
  44. 12 24
      AnKi/Scene/SceneGraph.cpp
  45. 11 68
      AnKi/Scene/SceneGraph.h
  46. 2 12
      AnKi/Scene/SceneNode.cpp
  47. 6 10
      AnKi/Scene/SceneNode.h
  48. 2 2
      AnKi/Scene/Visibility.cpp
  49. 8 8
      AnKi/Ui/Canvas.cpp
  50. 15 0
      AnKi/Ui/Common.h
  51. 6 6
      AnKi/Ui/Font.cpp
  52. 3 13
      AnKi/Ui/UiManager.cpp
  53. 11 36
      AnKi/Ui/UiManager.h
  54. 5 0
      AnKi/Ui/UiObject.cpp
  55. 2 0
      AnKi/Ui/UiObject.h
  56. 3 3
      Tests/Framework/Framework.cpp
  57. 1 1
      Tests/Resource/ResourceManager.cpp
  58. 9 1
      Tests/Ui/Ui.cpp
  59. 4 4
      Tools/Image/ImageViewerMain.cpp

+ 27 - 8
AnKi/Core/App.cpp

@@ -317,9 +317,9 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	// Resources
 	//
 	ResourceManagerInitInfo rinit;
-	rinit.m_gr = m_gr;
-	rinit.m_physics = m_physics;
-	rinit.m_resourceFs = m_resourceFs;
+	rinit.m_grManager = m_gr;
+	rinit.m_physicsWorld = m_physics;
+	rinit.m_resourceFilesystem = m_resourceFs;
 	rinit.m_unifiedGometryMemoryPool = m_unifiedGometryMemPool;
 	rinit.m_config = m_config;
 	rinit.m_allocCallback = m_mainPool.getAllocationCallback();
@@ -331,9 +331,16 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	//
 	// UI
 	//
+	UiManagerInitInfo uiInitInfo;
+	uiInitInfo.m_allocCallback = m_mainPool.getAllocationCallback();
+	uiInitInfo.m_allocCallbackUserData = m_mainPool.getAllocationCallbackUserData();
+	uiInitInfo.m_grManager = m_gr;
+	uiInitInfo.m_input = m_input;
+	uiInitInfo.m_resourceFilesystem = m_resourceFs;
+	uiInitInfo.m_resourceManager = m_resources;
+	uiInitInfo.m_stagingGpuMemoryPool = m_stagingMem;
 	m_ui = newInstance<UiManager>(m_mainPool);
-	ANKI_CHECK(m_ui->init(m_mainPool.getAllocationCallback(), m_mainPool.getAllocationCallbackUserData(), m_resources,
-						  m_gr, m_stagingMem, m_input));
+	ANKI_CHECK(m_ui->init(uiInitInfo));
 
 	//
 	// Renderer
@@ -363,9 +370,21 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	//
 	m_scene = newInstance<SceneGraph>(m_mainPool);
 
-	ANKI_CHECK(m_scene->init(m_mainPool.getAllocationCallback(), m_mainPool.getAllocationCallbackUserData(),
-							 m_threadHive, m_resources, m_input, m_script, m_ui, m_config, &m_globalTimestamp,
-							 m_unifiedGometryMemPool));
+	SceneGraphInitInfo sceneInit;
+	sceneInit.m_allocCallback = m_mainPool.getAllocationCallback();
+	sceneInit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
+	sceneInit.m_config = m_config;
+	sceneInit.m_globalTimestamp = &m_globalTimestamp;
+	sceneInit.m_gpuSceneMemoryPool = m_gpuSceneMemPool;
+	sceneInit.m_input = m_input;
+	sceneInit.m_resourceManager = m_resources;
+	sceneInit.m_scriptManager = m_script;
+	sceneInit.m_threadHive = m_threadHive;
+	sceneInit.m_uiManager = m_ui;
+	sceneInit.m_unifiedGeometryMemPool = m_unifiedGometryMemPool;
+	sceneInit.m_grManager = m_gr;
+	sceneInit.m_physicsWorld = m_physics;
+	ANKI_CHECK(m_scene->init(sceneInit));
 
 	// Inform the script engine about some subsystems
 	m_script->setRenderer(m_renderer);

+ 13 - 0
AnKi/Resource/Common.h

@@ -20,6 +20,9 @@ class ResourceFilesystem;
 template<typename Type>
 class ResourcePointer;
 class TransferGpuAllocatorHandle;
+class PhysicsWorld;
+class ConfigSet;
+class UnifiedGeometryMemoryPool;
 
 /// @addtogroup resource
 /// @{
@@ -55,6 +58,16 @@ using ResourcePtr = IntrusivePtr<T, ResourcePtrDeleter<T>>;
 
 /// An alias that denotes a ResourceFilesystem path.
 using ResourceFilename = CString;
+
+class ResourceManagerExternalSubsystems
+{
+public:
+	GrManager* m_grManager = nullptr;
+	PhysicsWorld* m_physicsWorld = nullptr;
+	ResourceFilesystem* m_resourceFilesystem = nullptr;
+	ConfigSet* m_config = nullptr;
+	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
+};
 /// @}
 
 } // end namespace anki

+ 3 - 2
AnKi/Resource/CpuMeshResource.cpp

@@ -23,7 +23,7 @@ CpuMeshResource::~CpuMeshResource()
 
 Error CpuMeshResource::load(const ResourceFilename& filename, [[maybe_unused]] Bool async)
 {
-	MeshBinaryLoader loader(&getManager());
+	MeshBinaryLoader loader(getExternalSubsystems().m_resourceFilesystem, &getTempMemoryPool());
 
 	ANKI_CHECK(loader.load(filename));
 
@@ -37,7 +37,8 @@ Error CpuMeshResource::load(const ResourceFilename& filename, [[maybe_unused]] B
 
 	// Create the collision shape
 	const Bool convex = !!(loader.getHeader().m_flags & MeshBinaryFlag::kConvex);
-	m_physicsShape = getManager().getPhysicsWorld().newInstance<PhysicsTriangleSoup>(m_positions, m_indices, convex);
+	m_physicsShape =
+		getExternalSubsystems().m_physicsWorld->newInstance<PhysicsTriangleSoup>(m_positions, m_indices, convex);
 
 	return Error::kNone;
 }

+ 5 - 5
AnKi/Resource/ImageResource.cpp

@@ -78,7 +78,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	ResourceFilePtr file;
 	ANKI_CHECK(openFile(filename, file));
 
-	ANKI_CHECK(loader.load(file, filename, getConfig().getRsrcMaxImageSize()));
+	ANKI_CHECK(loader.load(file, filename, getExternalSubsystems().m_config->getRsrcMaxImageSize()));
 
 	// Various sizes
 	init.m_width = loader.getWidth();
@@ -204,13 +204,13 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	init.m_mipmapCount = U8(loader.getMipmapCount());
 
 	// Create the texture
-	m_tex = getManager().getGrManager().newTexture(init);
+	m_tex = getExternalSubsystems().m_grManager->newTexture(init);
 
 	// Transition it. TODO remove that eventually
 	{
 		CommandBufferInitInfo cmdbinit;
 		cmdbinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
-		CommandBufferPtr cmdb = getManager().getGrManager().newCommandBuffer(cmdbinit);
+		CommandBufferPtr cmdb = getExternalSubsystems().m_grManager->newCommandBuffer(cmdbinit);
 
 		TextureSubresourceInfo subresource;
 		subresource.m_faceCount = textureTypeIsCube(init.m_type) ? 6 : 1;
@@ -229,7 +229,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	// Set the context
 	ctx->m_faces = faces;
 	ctx->m_layerCount = init.m_layerCount;
-	ctx->m_gr = &getManager().getGrManager();
+	ctx->m_gr = getExternalSubsystems().m_grManager;
 	ctx->m_trfAlloc = &getManager().getTransferGpuAllocator();
 	ctx->m_texType = init.m_type;
 	ctx->m_tex = m_tex;
@@ -249,7 +249,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 
 	// Create the texture view
 	TextureViewInitInfo viewInit(m_tex, "Rsrc");
-	m_texView = getManager().getGrManager().newTextureView(viewInit);
+	m_texView = getExternalSubsystems().m_grManager->newTextureView(viewInit);
 
 	return Error::kNone;
 }

+ 1 - 1
AnKi/Resource/MaterialResource.cpp

@@ -211,7 +211,7 @@ Error MaterialResource::parseShaderProgram(XmlElement shaderProgramEl, Bool asyn
 	CString shaderName;
 	ANKI_CHECK(shaderProgramEl.getAttributeText("name", shaderName));
 
-	if(!getManager().getGrManager().getDeviceCapabilities().m_rayTracingEnabled && shaderName.find("Rt") == 0)
+	if(!getExternalSubsystems().m_grManager->getDeviceCapabilities().m_rayTracingEnabled && shaderName.find("Rt") == 0)
 	{
 		// Skip RT programs when RT is disabled
 		return Error::kNone;

+ 1 - 6
AnKi/Resource/MeshBinaryLoader.cpp

@@ -8,11 +8,6 @@
 
 namespace anki {
 
-MeshBinaryLoader::MeshBinaryLoader(ResourceManager* manager)
-	: MeshBinaryLoader(manager, &manager->getTempMemoryPool())
-{
-}
-
 MeshBinaryLoader::~MeshBinaryLoader()
 {
 	m_subMeshes.destroy(*m_pool);
@@ -21,7 +16,7 @@ MeshBinaryLoader::~MeshBinaryLoader()
 Error MeshBinaryLoader::load(const ResourceFilename& filename)
 {
 	// Load header + submeshes
-	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, m_file));
+	ANKI_CHECK(m_fs->openFile(filename, m_file));
 	ANKI_CHECK(m_file->read(&m_header, sizeof(m_header)));
 	ANKI_CHECK(checkHeader());
 	ANKI_CHECK(loadSubmeshes());

+ 4 - 6
AnKi/Resource/MeshBinaryLoader.h

@@ -26,13 +26,11 @@ namespace anki {
 class MeshBinaryLoader
 {
 public:
-	MeshBinaryLoader(ResourceManager* manager);
-
-	MeshBinaryLoader(ResourceManager* manager, BaseMemoryPool* pool)
-		: m_manager(manager)
+	MeshBinaryLoader(ResourceFilesystem* fs, BaseMemoryPool* pool)
+		: m_fs(fs)
 		, m_pool(pool)
 	{
-		ANKI_ASSERT(manager && pool);
+		ANKI_ASSERT(fs && pool);
 	}
 
 	~MeshBinaryLoader();
@@ -58,7 +56,7 @@ public:
 	}
 
 private:
-	ResourceManager* m_manager = nullptr;
+	ResourceFilesystem* m_fs = nullptr;
 	BaseMemoryPool* m_pool = nullptr;
 	ResourceFilePtr m_file;
 

+ 17 - 17
AnKi/Resource/MeshResource.cpp

@@ -21,7 +21,7 @@ public:
 
 	LoadContext(MeshResource* mesh, BaseMemoryPool* pool)
 		: m_mesh(mesh)
-		, m_loader(&mesh->getManager(), pool)
+		, m_loader(mesh->getExternalSubsystems().m_resourceFilesystem, pool)
 	{
 	}
 };
@@ -59,11 +59,11 @@ MeshResource::~MeshResource()
 
 	for(Lod& lod : m_lods)
 	{
-		getManager().getUnifiedGeometryMemoryPool().free(lod.m_indexBufferAllocationToken);
+		getExternalSubsystems().m_unifiedGometryMemoryPool->free(lod.m_indexBufferAllocationToken);
 
 		for(VertexStreamId stream : EnumIterable(VertexStreamId::kMeshRelatedFirst, VertexStreamId::kMeshRelatedCount))
 		{
-			getManager().getUnifiedGeometryMemoryPool().free(lod.m_vertexBuffersAllocationToken[stream]);
+			getExternalSubsystems().m_unifiedGometryMemoryPool->free(lod.m_vertexBuffersAllocationToken[stream]);
 		}
 	}
 
@@ -79,7 +79,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	StringRaii basename(&getTempMemoryPool());
 	getFilepathFilename(filename, basename);
 
-	const Bool rayTracingEnabled = getManager().getGrManager().getDeviceCapabilities().m_rayTracingEnabled;
+	const Bool rayTracingEnabled = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_rayTracingEnabled;
 
 	if(async)
 	{
@@ -124,8 +124,8 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 		lod.m_indexCount = header.m_totalIndexCounts[l];
 		ANKI_ASSERT((lod.m_indexCount % 3) == 0 && "Expecting triangles");
 		const PtrSize indexBufferSize = PtrSize(lod.m_indexCount) * getIndexSize(m_indexType);
-		getManager().getUnifiedGeometryMemoryPool().allocate(indexBufferSize, getIndexSize(m_indexType),
-															 lod.m_indexBufferAllocationToken);
+		getExternalSubsystems().m_unifiedGometryMemoryPool->allocate(indexBufferSize, getIndexSize(m_indexType),
+																	 lod.m_indexBufferAllocationToken);
 
 		// Vertex stuff
 		lod.m_vertexCount = header.m_totalVertexCounts[l];
@@ -141,8 +141,8 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 			const U32 texelSize = getFormatInfo(kMeshRelatedVertexStreamFormats[stream]).m_texelSize;
 			const PtrSize vertexBufferSize = PtrSize(lod.m_vertexCount) * texelSize;
 			const U32 alignment = 4;
-			getManager().getUnifiedGeometryMemoryPool().allocate(vertexBufferSize, alignment,
-																 lod.m_vertexBuffersAllocationToken[stream]);
+			getExternalSubsystems().m_unifiedGometryMemoryPool->allocate(vertexBufferSize, alignment,
+																		 lod.m_vertexBuffersAllocationToken[stream]);
 		}
 
 		// BLAS
@@ -152,11 +152,11 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 				StringRaii(&getTempMemoryPool()).sprintf("%s_%s", "Blas", basename.cstr()));
 			inf.m_type = AccelerationStructureType::kBottomLevel;
 
-			inf.m_bottomLevel.m_indexBuffer = getManager().getUnifiedGeometryMemoryPool().getBuffer();
+			inf.m_bottomLevel.m_indexBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 			inf.m_bottomLevel.m_indexBufferOffset = lod.m_indexBufferAllocationToken.m_offset;
 			inf.m_bottomLevel.m_indexCount = lod.m_indexCount;
 			inf.m_bottomLevel.m_indexType = m_indexType;
-			inf.m_bottomLevel.m_positionBuffer = getManager().getUnifiedGeometryMemoryPool().getBuffer();
+			inf.m_bottomLevel.m_positionBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 			inf.m_bottomLevel.m_positionBufferOffset =
 				lod.m_vertexBuffersAllocationToken[VertexStreamId::kPosition].m_offset;
 			inf.m_bottomLevel.m_positionStride =
@@ -164,7 +164,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 			inf.m_bottomLevel.m_positionsFormat = kMeshRelatedVertexStreamFormats[VertexStreamId::kPosition];
 			inf.m_bottomLevel.m_positionCount = lod.m_vertexCount;
 
-			lod.m_blas = getManager().getGrManager().newAccelerationStructure(inf);
+			lod.m_blas = getExternalSubsystems().m_grManager->newAccelerationStructure(inf);
 		}
 	}
 
@@ -173,11 +173,11 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	{
 		CommandBufferInitInfo cmdbinit("MeshResourceClear");
 		cmdbinit.m_flags = CommandBufferFlag::kSmallBatch | CommandBufferFlag::kGeneralWork;
-		CommandBufferPtr cmdb = getManager().getGrManager().newCommandBuffer(cmdbinit);
+		CommandBufferPtr cmdb = getExternalSubsystems().m_grManager->newCommandBuffer(cmdbinit);
 
 		for(const Lod& lod : m_lods)
 		{
-			cmdb->fillBuffer(getManager().getUnifiedGeometryMemoryPool().getBuffer(),
+			cmdb->fillBuffer(getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer(),
 							 lod.m_indexBufferAllocationToken.m_offset,
 							 PtrSize(lod.m_indexCount) * getIndexSize(m_indexType), 0);
 
@@ -186,7 +186,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 			{
 				if(header.m_vertexAttributes[stream].m_format != Format::kNone)
 				{
-					cmdb->fillBuffer(getManager().getUnifiedGeometryMemoryPool().getBuffer(),
+					cmdb->fillBuffer(getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer(),
 									 lod.m_vertexBuffersAllocationToken[stream].m_offset,
 									 PtrSize(lod.m_vertexCount)
 										 * getFormatInfo(kMeshRelatedVertexStreamFormats[stream]).m_texelSize,
@@ -195,7 +195,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 			}
 		}
 
-		const BufferBarrierInfo barrier = {getManager().getUnifiedGeometryMemoryPool().getBuffer().get(),
+		const BufferBarrierInfo barrier = {getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer().get(),
 										   BufferUsageBit::kTransferDestination, BufferUsageBit::kVertex, 0,
 										   kMaxPtrSize};
 
@@ -221,13 +221,13 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 
 Error MeshResource::loadAsync(MeshBinaryLoader& loader) const
 {
-	GrManager& gr = getManager().getGrManager();
+	GrManager& gr = *getExternalSubsystems().m_grManager;
 	TransferGpuAllocator& transferAlloc = getManager().getTransferGpuAllocator();
 
 	Array<TransferGpuAllocatorHandle, kMaxLodCount*(U32(VertexStreamId::kMeshRelatedCount) + 1)> handles;
 	U32 handleCount = 0;
 
-	BufferPtr unifiedGeometryBuffer = getManager().getUnifiedGeometryMemoryPool().getBuffer();
+	BufferPtr unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 	const BufferUsageBit unifiedGeometryBufferNonTransferUsage =
 		unifiedGeometryBuffer->getBufferUsage() ^ BufferUsageBit::kTransferDestination;
 

+ 4 - 8
AnKi/Resource/ResourceManager.cpp

@@ -41,12 +41,7 @@ ResourceManager::~ResourceManager()
 Error ResourceManager::init(ResourceManagerInitInfo& init)
 {
 	ANKI_RESOURCE_LOGI("Initializing resource manager");
-
-	m_gr = init.m_gr;
-	m_physics = init.m_physics;
-	m_fs = init.m_resourceFs;
-	m_config = init.m_config;
-	m_unifiedGometryMemoryPool = init.m_unifiedGometryMemoryPool;
+	m_subsystems = init;
 
 	m_pool.init(init.m_allocCallback, init.m_allocCallbackData, "Resources");
 	m_tmpPool.init(init.m_allocCallback, init.m_allocCallbackData, 10_MB);
@@ -63,11 +58,12 @@ Error ResourceManager::init(ResourceManagerInitInfo& init)
 	m_asyncLoader->init(&m_pool);
 
 	m_transferGpuAlloc = newInstance<TransferGpuAllocator>(m_pool);
-	ANKI_CHECK(m_transferGpuAlloc->init(m_config->getRsrcTransferScratchMemorySize(), m_gr, &m_pool));
+	ANKI_CHECK(m_transferGpuAlloc->init(m_subsystems.m_config->getRsrcTransferScratchMemorySize(),
+										m_subsystems.m_grManager, &m_pool));
 
 	// Init the programs
 	m_shaderProgramSystem = newInstance<ShaderProgramResourceSystem>(m_pool, &m_pool);
-	ANKI_CHECK(m_shaderProgramSystem->init(*m_fs, *m_gr));
+	ANKI_CHECK(m_shaderProgramSystem->init(*m_subsystems.m_resourceFilesystem, *m_subsystems.m_grManager));
 
 	return Error::kNone;
 }

+ 3 - 41
AnKi/Resource/ResourceManager.h

@@ -88,14 +88,9 @@ private:
 	}
 };
 
-class ResourceManagerInitInfo
+class ResourceManagerInitInfo : public ResourceManagerExternalSubsystems
 {
 public:
-	GrManager* m_gr = nullptr;
-	PhysicsWorld* m_physics = nullptr;
-	ResourceFilesystem* m_resourceFs = nullptr;
-	ConfigSet* m_config = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
 	AllocAlignedCallback m_allocCallback = 0;
 	void* m_allocCallbackData = nullptr;
 };
@@ -116,6 +111,7 @@ public \
 {
 	template<typename T>
 	friend class ResourcePtrDeleter;
+	friend class ResourceObject;
 
 public:
 	ResourceManager();
@@ -140,29 +136,11 @@ public:
 		return m_tmpPool;
 	}
 
-	ANKI_INTERNAL GrManager& getGrManager()
-	{
-		ANKI_ASSERT(m_gr);
-		return *m_gr;
-	}
-
 	ANKI_INTERNAL TransferGpuAllocator& getTransferGpuAllocator()
 	{
 		return *m_transferGpuAlloc;
 	}
 
-	ANKI_INTERNAL PhysicsWorld& getPhysicsWorld()
-	{
-		ANKI_ASSERT(m_physics);
-		return *m_physics;
-	}
-
-	ANKI_INTERNAL ResourceFilesystem& getFilesystem()
-	{
-		ANKI_ASSERT(m_fs);
-		return *m_fs;
-	}
-
 	template<typename T>
 	ANKI_INTERNAL T* findLoadedResource(const CString& filename)
 	{
@@ -201,28 +179,12 @@ public:
 		return *m_shaderProgramSystem;
 	}
 
-	UnifiedGeometryMemoryPool& getUnifiedGeometryMemoryPool()
-	{
-		ANKI_ASSERT(m_unifiedGometryMemoryPool);
-		return *m_unifiedGometryMemoryPool;
-	}
-
-	const ConfigSet& getConfig() const
-	{
-		ANKI_ASSERT(m_config);
-		return *m_config;
-	}
-
 private:
-	GrManager* m_gr = nullptr;
-	PhysicsWorld* m_physics = nullptr;
-	ResourceFilesystem* m_fs = nullptr;
-	ConfigSet* m_config = nullptr;
+	ResourceManagerExternalSubsystems m_subsystems;
 	mutable HeapMemoryPool m_pool; ///< Mutable because it's thread-safe and is may be called by const methods.
 	mutable StackMemoryPool m_tmpPool; ///< Same as above.
 	AsyncLoader* m_asyncLoader = nullptr; ///< Async loading thread
 	ShaderProgramResourceSystem* m_shaderProgramSystem = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
 	U64 m_uuid = 0;
 	U64 m_loadRequestCount = 0;
 	TransferGpuAllocator* m_transferGpuAlloc = nullptr;

+ 4 - 4
AnKi/Resource/ResourceObject.cpp

@@ -32,14 +32,14 @@ StackMemoryPool& ResourceObject::getTempMemoryPool() const
 
 Error ResourceObject::openFile(const CString& filename, ResourceFilePtr& file)
 {
-	return m_manager->getFilesystem().openFile(filename, file);
+	return getExternalSubsystems().m_resourceFilesystem->openFile(filename, file);
 }
 
 Error ResourceObject::openFileReadAllText(const CString& filename, StringRaii& text)
 {
 	// Load file
 	ResourceFilePtr file;
-	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, file));
+	ANKI_CHECK(getExternalSubsystems().m_resourceFilesystem->openFile(filename, file));
 
 	// Read string
 	ANKI_CHECK(file->readAllText(text));
@@ -57,9 +57,9 @@ Error ResourceObject::openFileParseXml(const CString& filename, XmlDocument& xml
 	return Error::kNone;
 }
 
-const ConfigSet& ResourceObject::getConfig() const
+ResourceManagerExternalSubsystems& ResourceObject::getExternalSubsystems() const
 {
-	return m_manager->getConfig();
+	return m_manager->m_subsystems;
 }
 
 } // end namespace anki

+ 11 - 8
AnKi/Resource/ResourceObject.h

@@ -14,6 +14,7 @@ namespace anki {
 
 // Forward
 class XmlDocument;
+class GrManager;
 
 /// @addtogroup resource
 /// @{
@@ -22,18 +23,14 @@ class XmlDocument;
 class ResourceObject
 {
 	friend class ResourceManager;
+	template<typename>
+	friend class ResourcePtrDeleter;
 
 public:
 	ResourceObject(ResourceManager* manager);
 
 	virtual ~ResourceObject();
 
-	/// @privatesection
-	ResourceManager& getManager() const
-	{
-		return *m_manager;
-	}
-
 	HeapMemoryPool& getMemoryPool() const;
 	StackMemoryPool& getTempMemoryPool() const;
 
@@ -60,8 +57,6 @@ public:
 
 	// Internals:
 
-	ANKI_INTERNAL const ConfigSet& getConfig() const;
-
 	ANKI_INTERNAL void setFilename(const CString& fname)
 	{
 		ANKI_ASSERT(m_fname.isEmpty());
@@ -87,6 +82,14 @@ public:
 
 	ANKI_INTERNAL Error openFileParseXml(const ResourceFilename& filename, XmlDocument& xml);
 
+protected:
+	ResourceManager& getManager() const
+	{
+		return *m_manager;
+	}
+
+	ResourceManagerExternalSubsystems& getExternalSubsystems() const;
+
 private:
 	ResourceManager* m_manager;
 	mutable Atomic<I32> m_refcount;

+ 2 - 2
AnKi/Resource/ShaderProgramResource.cpp

@@ -392,7 +392,7 @@ ShaderProgramResource::createNewVariant(const ShaderProgramResourceVariantInitIn
 			inf.m_shaderType = shaderType;
 			inf.m_binary = binary.m_codeBlocks[binaryVariant->m_codeBlockIndices[shaderType]].m_binary;
 			inf.m_constValues.setArray((constValueCount) ? constValues.getBegin() : nullptr, constValueCount);
-			ShaderPtr shader = getManager().getGrManager().newShader(inf);
+			ShaderPtr shader = getExternalSubsystems().m_grManager->newShader(inf);
 
 			const ShaderTypeBit shaderBit = ShaderTypeBit(1 << shaderType);
 			if(!!(shaderBit & ShaderTypeBit::kAllGraphics))
@@ -410,7 +410,7 @@ ShaderProgramResource::createNewVariant(const ShaderProgramResourceVariantInitIn
 		}
 
 		// Create the program
-		variant->m_prog = getManager().getGrManager().newShaderProgram(progInf);
+		variant->m_prog = getExternalSubsystems().m_grManager->newShaderProgram(progInf);
 	}
 	else
 	{

+ 12 - 12
AnKi/Scene/CameraNode.cpp

@@ -62,29 +62,29 @@ void CameraNode::initCommon(FrustumType frustumType)
 	frc->setFrustumType(frustumType);
 	frc->setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::kAll
 								   ^ FrustumComponentVisibilityTestFlag::kAllRayTracing);
-	frc->setLodDistance(0, getConfig().getLod0MaxDistance());
-	frc->setLodDistance(1, getConfig().getLod1MaxDistance());
-	frc->setShadowCascadeCount(getConfig().getSceneShadowCascadeCount());
+	frc->setLodDistance(0, getExternalSubsystems().m_config->getLod0MaxDistance());
+	frc->setLodDistance(1, getExternalSubsystems().m_config->getLod1MaxDistance());
+	frc->setShadowCascadeCount(getExternalSubsystems().m_config->getSceneShadowCascadeCount());
 
 	static_assert(kMaxShadowCascades == 4);
-	frc->setShadowCascadeDistance(0, getConfig().getSceneShadowCascade0Distance());
-	frc->setShadowCascadeDistance(1, getConfig().getSceneShadowCascade1Distance());
-	frc->setShadowCascadeDistance(2, getConfig().getSceneShadowCascade2Distance());
-	frc->setShadowCascadeDistance(3, getConfig().getSceneShadowCascade3Distance());
+	frc->setShadowCascadeDistance(0, getExternalSubsystems().m_config->getSceneShadowCascade0Distance());
+	frc->setShadowCascadeDistance(1, getExternalSubsystems().m_config->getSceneShadowCascade1Distance());
+	frc->setShadowCascadeDistance(2, getExternalSubsystems().m_config->getSceneShadowCascade2Distance());
+	frc->setShadowCascadeDistance(3, getExternalSubsystems().m_config->getSceneShadowCascade3Distance());
 
 	// Extended frustum for RT
-	if(getSceneGraph().getGrManager().getDeviceCapabilities().m_rayTracingEnabled
-	   && getConfig().getSceneRayTracedShadows())
+	if(getExternalSubsystems().m_grManager->getDeviceCapabilities().m_rayTracingEnabled
+	   && getExternalSubsystems().m_config->getSceneRayTracedShadows())
 	{
 		FrustumComponent* rtFrustumComponent = newComponent<FrustumComponent>();
 		rtFrustumComponent->setFrustumType(FrustumType::kOrthographic);
 		rtFrustumComponent->setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::kRayTracingShadows);
 
-		const F32 dist = getConfig().getSceneRayTracingExtendedFrustumDistance();
+		const F32 dist = getExternalSubsystems().m_config->getSceneRayTracingExtendedFrustumDistance();
 
 		rtFrustumComponent->setOrthographic(0.1f, dist * 2.0f, dist, -dist, dist, -dist);
-		rtFrustumComponent->setLodDistance(0, getConfig().getLod0MaxDistance());
-		rtFrustumComponent->setLodDistance(1, getConfig().getLod1MaxDistance());
+		rtFrustumComponent->setLodDistance(0, getExternalSubsystems().m_config->getLod0MaxDistance());
+		rtFrustumComponent->setLodDistance(1, getExternalSubsystems().m_config->getLod1MaxDistance());
 	}
 }
 

+ 27 - 0
AnKi/Scene/Common.h

@@ -11,6 +11,17 @@
 
 namespace anki {
 
+// Forward
+class ResourceManager;
+class Input;
+class ConfigSet;
+class UiManager;
+class UnifiedGeometryMemoryPool;
+class GpuSceneMemoryPool;
+class ScriptManager;
+class GrManager;
+class PhysicsWorld;
+
 /// @addtogroup scene
 /// @{
 
@@ -28,6 +39,22 @@ namespace anki {
 		} \
 		return ok; \
 	}))
+
+class SceneGraphExternalSubsystems
+{
+public:
+	ConfigSet* m_config = nullptr;
+	ThreadHive* m_threadHive = nullptr;
+	ResourceManager* m_resourceManager = nullptr;
+	Input* m_input = nullptr;
+	ScriptManager* m_scriptManager = nullptr;
+	UiManager* m_uiManager = nullptr;
+	GrManager* m_grManager = nullptr;
+	const Timestamp* m_globalTimestamp = nullptr;
+	PhysicsWorld* m_physicsWorld = nullptr;
+	UnifiedGeometryMemoryPool* m_unifiedGeometryMemPool = nullptr;
+	GpuSceneMemoryPool* m_gpuSceneMemoryPool = nullptr;
+};
 /// @}
 
 } // end namespace anki

+ 3 - 3
AnKi/Scene/Components/BodyComponent.cpp

@@ -27,7 +27,7 @@ BodyComponent::~BodyComponent()
 Error BodyComponent::loadMeshResource(CString meshFilename)
 {
 	m_body.reset(nullptr);
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(meshFilename, m_mesh));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(meshFilename, m_mesh));
 
 	const Transform prevTransform = (m_body) ? m_body->getTransform() : m_trf;
 	const F32 prevMass = (m_body) ? m_body->getMass() : 0.0f;
@@ -36,7 +36,7 @@ Error BodyComponent::loadMeshResource(CString meshFilename)
 	init.m_mass = prevMass;
 	init.m_transform = prevTransform;
 	init.m_shape = m_mesh->getCollisionShape();
-	m_body = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsBody>(init);
+	m_body = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsBody>(init);
 	m_body->setUserData(this);
 
 	m_markedForUpdate = true;
@@ -67,7 +67,7 @@ void BodyComponent::setMass(F32 mass)
 			init.m_transform = prevTransform;
 			init.m_mass = mass;
 			init.m_shape = m_mesh->getCollisionShape();
-			m_body = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsBody>(init);
+			m_body = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsBody>(init);
 			m_body->setUserData(this);
 
 			m_markedForUpdate = true;

+ 2 - 2
AnKi/Scene/Components/DecalComponent.cpp

@@ -17,7 +17,7 @@ DecalComponent::DecalComponent(SceneNode* node)
 	, m_node(node)
 {
 	ANKI_ASSERT(node);
-	if(node->getSceneGraph().getResourceManager().loadResource("EngineAssets/GreenDecal.ankitex", m_debugImage))
+	if(getExternalSubsystems(*m_node).m_resourceManager->loadResource("EngineAssets/GreenDecal.ankitex", m_debugImage))
 	{
 		ANKI_SCENE_LOGF("Failed to load resources");
 	}
@@ -31,7 +31,7 @@ Error DecalComponent::setLayer(CString texAtlasFname, CString texAtlasSubtexName
 {
 	Layer& l = m_layers[type];
 
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(texAtlasFname, l.m_atlas));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(texAtlasFname, l.m_atlas));
 
 	ANKI_CHECK(l.m_atlas->getSubImageInfo(texAtlasSubtexName, &l.m_uv[0]));
 

+ 1 - 1
AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp

@@ -20,7 +20,7 @@ GlobalIlluminationProbeComponent::GlobalIlluminationProbeComponent(SceneNode* no
 	, m_markedForRendering(false)
 	, m_shapeDirty(true)
 {
-	if(node->getSceneGraph().getResourceManager().loadResource("EngineAssets/GiProbe.ankitex", m_debugImage))
+	if(getExternalSubsystems(*m_node).m_resourceManager->loadResource("EngineAssets/GiProbe.ankitex", m_debugImage))
 	{
 		ANKI_SCENE_LOGF("Failed to load resources");
 	}

+ 8 - 8
AnKi/Scene/Components/GpuParticleEmitterComponent.cpp

@@ -31,17 +31,17 @@ Error GpuParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 	// Create the debug drawer
 	if(!m_dbgImage.isCreated())
 	{
-		ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource("EngineAssets/ParticleEmitter.ankitex",
-																			 m_dbgImage));
+		ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(
+			"EngineAssets/ParticleEmitter.ankitex", m_dbgImage));
 	}
 
 	// Load particle props
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(filename, m_particleEmitterResource));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(filename, m_particleEmitterResource));
 	const ParticleEmitterProperties& inProps = m_particleEmitterResource->getProperties();
 	m_maxParticleCount = inProps.m_maxNumOfParticles;
 
 	// Create program
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(
 		"ShaderBinaries/GpuParticlesSimulation.ankiprogbin", m_prog));
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variant);
@@ -54,7 +54,7 @@ Error GpuParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 		buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
 		buffInit.m_usage = BufferUsageBit::kUniformCompute;
 		buffInit.m_size = sizeof(GpuParticleEmitterProperties);
-		m_propsBuff = m_node->getSceneGraph().getGrManager().newBuffer(buffInit);
+		m_propsBuff = getExternalSubsystems(*m_node).m_grManager->newBuffer(buffInit);
 		GpuParticleEmitterProperties* props =
 			static_cast<GpuParticleEmitterProperties*>(m_propsBuff->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
 
@@ -80,7 +80,7 @@ Error GpuParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 		buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
 		buffInit.m_usage = BufferUsageBit::kAllStorage;
 		buffInit.m_size = sizeof(GpuParticle) * m_maxParticleCount;
-		m_particlesBuff = m_node->getSceneGraph().getGrManager().newBuffer(buffInit);
+		m_particlesBuff = getExternalSubsystems(*m_node).m_grManager->newBuffer(buffInit);
 
 		GpuParticle* particle =
 			static_cast<GpuParticle*>(m_particlesBuff->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
@@ -100,7 +100,7 @@ Error GpuParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 		buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
 		buffInit.m_usage = BufferUsageBit::kAllStorage;
 		buffInit.m_size = sizeof(U32) + kMaxRandFactors * sizeof(F32);
-		m_randFactorsBuff = m_node->getSceneGraph().getGrManager().newBuffer(buffInit);
+		m_randFactorsBuff = getExternalSubsystems(*m_node).m_grManager->newBuffer(buffInit);
 
 		F32* randFactors = static_cast<F32*>(m_randFactorsBuff->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
 
@@ -121,7 +121,7 @@ Error GpuParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 	{
 		SamplerInitInfo sinit("GpuParticles");
 		sinit.m_addressing = SamplingAddressing::kClamp;
-		m_nearestAnyClampSampler = m_node->getSceneGraph().getGrManager().newSampler(sinit);
+		m_nearestAnyClampSampler = getExternalSubsystems(*m_node).m_grManager->newSampler(sinit);
 	}
 
 	// Find the extend of the particles

+ 2 - 2
AnKi/Scene/Components/JointComponent.cpp

@@ -65,7 +65,7 @@ void JointComponent::newJoint(const Vec3& relPosFactor, F32 breakingImpulse, TAr
 	{
 		Vec3 relPos = computeLocalPivotFromFactors(bodyc->getPhysicsBody(), relPosFactor);
 
-		PhysicsJointPtr joint = m_node->getSceneGraph().getPhysicsWorld().newInstance<TJoint>(
+		PhysicsJointPtr joint = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<TJoint>(
 			bodyc->getPhysicsBody(), relPos, std::forward<TArgs>(args)...);
 		joint->setBreakingImpulseThreshold(breakingImpulse);
 
@@ -98,7 +98,7 @@ void JointComponent::newPoint2PointJoint2(const Vec3& relPosFactorA, const Vec3&
 		Vec3 relPosA = computeLocalPivotFromFactors(bodycA->getPhysicsBody(), relPosFactorA);
 		Vec3 relPosB = computeLocalPivotFromFactors(bodycB->getPhysicsBody(), relPosFactorB);
 
-		PhysicsJointPtr joint = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsPoint2PointJoint>(
+		PhysicsJointPtr joint = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsPoint2PointJoint>(
 			bodycA->getPhysicsBody(), relPosA, bodycB->getPhysicsBody(), relPosB);
 		joint->setBreakingImpulseThreshold(breakingImpulse);
 

+ 1 - 1
AnKi/Scene/Components/LensFlareComponent.cpp

@@ -25,7 +25,7 @@ LensFlareComponent::~LensFlareComponent()
 
 Error LensFlareComponent::loadImageResource(CString filename)
 {
-	return m_node->getSceneGraph().getResourceManager().loadResource(filename, m_image);
+	return getExternalSubsystems(*m_node).m_resourceManager->loadResource(filename, m_image);
 }
 
 } // end namespace anki

+ 3 - 2
AnKi/Scene/Components/LightComponent.cpp

@@ -28,8 +28,9 @@ LightComponent::LightComponent(SceneNode* node)
 	ANKI_ASSERT(m_uuid > 0);
 	m_point.m_radius = 1.0f;
 
-	if(node->getSceneGraph().getResourceManager().loadResource("EngineAssets/LightBulb.ankitex", m_pointDebugImage)
-	   || node->getSceneGraph().getResourceManager().loadResource("EngineAssets/SpotLight.ankitex", m_spotDebugImage))
+	if(getExternalSubsystems(*node).m_resourceManager->loadResource("EngineAssets/LightBulb.ankitex", m_pointDebugImage)
+	   || getExternalSubsystems(*node).m_resourceManager->loadResource("EngineAssets/SpotLight.ankitex",
+																	   m_spotDebugImage))
 	{
 		ANKI_SCENE_LOGF("Failed to load resources");
 	}

+ 1 - 1
AnKi/Scene/Components/ModelComponent.cpp

@@ -29,7 +29,7 @@ Error ModelComponent::loadModelResource(CString filename)
 	m_dirty = true;
 
 	ModelResourcePtr rsrc;
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(filename, rsrc));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(filename, rsrc));
 	m_model = std::move(rsrc);
 
 	m_modelPatchMergeKeys.destroy(m_node->getMemoryPool());

+ 7 - 6
AnKi/Scene/Components/ParticleEmitterComponent.cpp

@@ -132,7 +132,7 @@ public:
 
 	PhysicsParticle(const PhysicsBodyInitInfo& init, SceneNode* node, ParticleEmitterComponent* component)
 	{
-		m_body = node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsBody>(init);
+		m_body = getExternalSubsystems(*node).m_physicsWorld->newInstance<PhysicsBody>(init);
 		m_body->setUserData(component);
 		m_body->activate(false);
 		m_body->setMaterialGroup(PhysicsMaterialBit::kParticle);
@@ -212,12 +212,12 @@ Error ParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 	// Create the debug drawer
 	if(!m_dbgImage.isCreated())
 	{
-		ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource("EngineAssets/ParticleEmitter.ankitex",
-																			 m_dbgImage));
+		ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(
+			"EngineAssets/ParticleEmitter.ankitex", m_dbgImage));
 	}
 
 	// Load
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(filename, m_particleEmitterResource));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(filename, m_particleEmitterResource));
 	m_props = m_particleEmitterResource->getProperties();
 
 	// Cleanup
@@ -228,8 +228,9 @@ Error ParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 	m_simulationType = (m_props.m_usePhysicsEngine) ? SimulationType::kPhysicsEngine : SimulationType::kSimple;
 	if(m_simulationType == SimulationType::kPhysicsEngine)
 	{
-		PhysicsCollisionShapePtr collisionShape = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsSphere>(
-			m_props.m_particle.m_minInitialSize / 2.0f);
+		PhysicsCollisionShapePtr collisionShape =
+			getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsSphere>(
+				m_props.m_particle.m_minInitialSize / 2.0f);
 
 		PhysicsBodyInitInfo binit;
 		binit.m_shape = std::move(collisionShape);

+ 1 - 1
AnKi/Scene/Components/PlayerControllerComponent.cpp

@@ -17,7 +17,7 @@ PlayerControllerComponent::PlayerControllerComponent(SceneNode* node)
 {
 	PhysicsPlayerControllerInitInfo init;
 	init.m_position = Vec3(0.0f);
-	m_player = node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsPlayerController>(init);
+	m_player = getExternalSubsystems(*node).m_physicsWorld->newInstance<PhysicsPlayerController>(init);
 	m_player->setUserData(this);
 }
 

+ 1 - 1
AnKi/Scene/Components/ReflectionProbeComponent.cpp

@@ -20,7 +20,7 @@ ReflectionProbeComponent::ReflectionProbeComponent(SceneNode* node)
 	, m_markedForRendering(false)
 	, m_markedForUpdate(true)
 {
-	if(node->getSceneGraph().getResourceManager().loadResource("EngineAssets/Mirror.ankitex", m_debugImage))
+	if(getExternalSubsystems(*node).m_resourceManager->loadResource("EngineAssets/Mirror.ankitex", m_debugImage))
 	{
 		ANKI_SCENE_LOGF("Failed to load resources");
 	}

+ 6 - 0
AnKi/Scene/Components/SceneComponent.cpp

@@ -4,6 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include <AnKi/Scene/Components/SceneComponent.h>
+#include <AnKi/Scene/SceneNode.h>
 
 namespace anki {
 
@@ -71,4 +72,9 @@ const SceneComponentRtti& SceneComponent::findClassRtti(U8 classId)
 	return *g_rttis[classId];
 }
 
+SceneGraphExternalSubsystems& SceneComponent::getExternalSubsystems(const SceneNode& node)
+{
+	return node.getExternalSubsystems();
+}
+
 } // namespace anki

+ 3 - 0
AnKi/Scene/Components/SceneComponent.h

@@ -115,6 +115,9 @@ public:
 
 	static const SceneComponentRtti& findClassRtti(U8 classId);
 
+protected:
+	static SceneGraphExternalSubsystems& getExternalSubsystems(const SceneNode& node);
+
 private:
 	Timestamp m_timestamp = 1; ///< Indicates when an update happened
 	U8 m_classId : 7; ///< Cache the type ID.

+ 2 - 2
AnKi/Scene/Components/ScriptComponent.cpp

@@ -29,7 +29,7 @@ ScriptComponent::~ScriptComponent()
 Error ScriptComponent::loadScriptResource(CString fname)
 {
 	// Load
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(fname, m_script));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(fname, m_script));
 
 	// Create the env
 	if(m_env)
@@ -37,7 +37,7 @@ Error ScriptComponent::loadScriptResource(CString fname)
 		deleteInstance(m_node->getMemoryPool(), m_env);
 	}
 	m_env = newInstance<ScriptEnvironment>(m_node->getMemoryPool());
-	ANKI_CHECK(m_env->init(&m_node->getSceneGraph().getScriptManager()));
+	ANKI_CHECK(m_env->init(getExternalSubsystems(*m_node).m_scriptManager));
 
 	// Exec the script
 	ANKI_CHECK(m_env->evalString(m_script->getSource()));

+ 1 - 1
AnKi/Scene/Components/SkinComponent.cpp

@@ -30,7 +30,7 @@ SkinComponent::~SkinComponent()
 
 Error SkinComponent::loadSkeletonResource(CString fname)
 {
-	ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(fname, m_skeleton));
+	ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(fname, m_skeleton));
 
 	m_boneTrfs[0].destroy(m_node->getMemoryPool());
 	m_boneTrfs[1].destroy(m_node->getMemoryPool());

+ 1 - 1
AnKi/Scene/Components/SkyboxComponent.cpp

@@ -26,7 +26,7 @@ SkyboxComponent::~SkyboxComponent()
 
 void SkyboxComponent::setImage(CString filename)
 {
-	const Error err = m_node->getSceneGraph().getResourceManager().loadResource(filename, m_image);
+	const Error err = getExternalSubsystems(*m_node).m_resourceManager->loadResource(filename, m_image);
 	if(err)
 	{
 		ANKI_SCENE_LOGE("Setting skybox image failed. Ignoring error");

+ 2 - 2
AnKi/Scene/Components/TriggerComponent.cpp

@@ -88,8 +88,8 @@ TriggerComponent::~TriggerComponent()
 
 void TriggerComponent::setSphereVolumeRadius(F32 radius)
 {
-	m_shape = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsSphere>(radius);
-	m_trigger = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsTrigger>(m_shape);
+	m_shape = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsSphere>(radius);
+	m_trigger = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsTrigger>(m_shape);
 	m_trigger->setUserData(this);
 	m_trigger->setContactProcessCallback(m_callbacks);
 }

+ 3 - 3
AnKi/Scene/DebugDrawer.cpp

@@ -65,7 +65,7 @@ void allocateAndPopulateDebugBox(StagingGpuMemoryPool& stagingGpuAllocator, Stag
 	indexCount = kIndexCount;
 }
 
-Error DebugDrawer2::init(ResourceManager* rsrcManager)
+Error DebugDrawer2::init(ResourceManager* rsrcManager, GrManager* gr)
 {
 	ANKI_CHECK(rsrcManager->loadResource("ShaderBinaries/SceneDebug.ankiprogbin", m_prog));
 
@@ -74,7 +74,7 @@ Error DebugDrawer2::init(ResourceManager* rsrcManager)
 		bufferInit.m_usage = BufferUsageBit::kVertex;
 		bufferInit.m_size = sizeof(Vec3) * 8;
 		bufferInit.m_mapAccess = BufferMapAccessBit::kWrite;
-		m_cubePositionsBuffer = rsrcManager->getGrManager().newBuffer(bufferInit);
+		m_cubePositionsBuffer = gr->newBuffer(bufferInit);
 
 		Vec3* verts = static_cast<Vec3*>(m_cubePositionsBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
 
@@ -99,7 +99,7 @@ Error DebugDrawer2::init(ResourceManager* rsrcManager)
 		bufferInit.m_usage = BufferUsageBit::kVertex;
 		bufferInit.m_size = sizeof(U16) * kIndexCount;
 		bufferInit.m_mapAccess = BufferMapAccessBit::kWrite;
-		m_cubeIndicesBuffer = rsrcManager->getGrManager().newBuffer(bufferInit);
+		m_cubeIndicesBuffer = gr->newBuffer(bufferInit);
 
 		U16* indices = static_cast<U16*>(m_cubeIndicesBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
 

+ 1 - 1
AnKi/Scene/DebugDrawer.h

@@ -30,7 +30,7 @@ void allocateAndPopulateDebugBox(StagingGpuMemoryPool& stagingGpuAllocator, Stag
 class DebugDrawer2
 {
 public:
-	Error init(ResourceManager* rsrcManager);
+	Error init(ResourceManager* rsrcManager, GrManager* gr);
 
 	Bool isInitialized() const
 	{

+ 1 - 1
AnKi/Scene/Events/AnimationEvent.cpp

@@ -19,7 +19,7 @@ AnimationEvent::AnimationEvent(EventManager* manager)
 Error AnimationEvent::init(CString animationFilename, CString channelName, SceneNode* movableSceneNode)
 {
 	ANKI_ASSERT(movableSceneNode);
-	ANKI_CHECK(getSceneGraph().getResourceManager().loadResource(animationFilename, m_anim));
+	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(animationFilename, m_anim));
 
 	m_channelIndex = 0;
 	for(const AnimationChannel& channel : m_anim->getChannels())

+ 7 - 2
AnKi/Scene/Events/Event.cpp

@@ -43,8 +43,8 @@ void Event::setMarkedForDeletion()
 
 Second Event::getDelta(Second crntTime) const
 {
-	Second d = crntTime - m_startTime; // delta
-	Second dp = d / m_duration; // delta as persentage
+	const Second d = crntTime - m_startTime; // delta
+	const Second dp = d / m_duration; // delta as persentage
 	return dp;
 }
 
@@ -58,4 +58,9 @@ const SceneGraph& Event::getSceneGraph() const
 	return m_manager->getSceneGraph();
 }
 
+SceneGraphExternalSubsystems& Event::getExternalSubsystems() const
+{
+	return m_manager->getSceneGraph().m_subsystems;
+}
+
 } // end namespace anki

+ 2 - 0
AnKi/Scene/Events/Event.h

@@ -118,6 +118,8 @@ protected:
 	/// Return the u between current time and when the event started
 	/// @return A number [0.0, 1.0]
 	Second getDelta(Second crntTime) const;
+
+	SceneGraphExternalSubsystems& getExternalSubsystems() const;
 };
 /// @}
 

+ 2 - 2
AnKi/Scene/Events/ScriptEvent.cpp

@@ -28,7 +28,7 @@ Error ScriptEvent::init(Second startTime, Second duration, CString script)
 	Event::init(startTime, duration);
 
 	// Create the env
-	ANKI_CHECK(m_env.init(&getSceneGraph().getScriptManager()));
+	ANKI_CHECK(m_env.init(getExternalSubsystems().m_scriptManager));
 
 	// Do the rest
 	StringRaii extension(&getMemoryPool());
@@ -37,7 +37,7 @@ Error ScriptEvent::init(Second startTime, Second duration, CString script)
 	if(!extension.isEmpty() && extension == "lua")
 	{
 		// It's a file
-		ANKI_CHECK(getSceneGraph().getResourceManager().loadResource(script, m_scriptRsrc));
+		ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(script, m_scriptRsrc));
 
 		// Exec the script
 		ANKI_CHECK(m_env.evalString(m_scriptRsrc->getSource()));

+ 4 - 2
AnKi/Scene/GlobalIlluminationProbeNode.cpp

@@ -149,7 +149,8 @@ void GlobalIlluminationProbeNode::onShapeUpdateOrProbeNeedsRendering()
 		// Compute effective distance
 		F32 effectiveDistance = max(gic.getBoxVolumeSize().x(), gic.getBoxVolumeSize().y());
 		effectiveDistance = max(effectiveDistance, gic.getBoxVolumeSize().z());
-		effectiveDistance = max(effectiveDistance, getConfig().getSceneReflectionProbeEffectiveDistance());
+		effectiveDistance =
+			max(effectiveDistance, getExternalSubsystems().m_config->getSceneReflectionProbeEffectiveDistance());
 
 		// Update frustum components
 		U count = 0;
@@ -160,7 +161,8 @@ void GlobalIlluminationProbeNode::onShapeUpdateOrProbeNeedsRendering()
 			frc.setWorldTransform(trf);
 			frc.setFar(effectiveDistance);
 			frc.setShadowCascadeDistance(
-				0, min(effectiveDistance, getConfig().getSceneReflectionProbeShadowEffectiveDistance()));
+				0, min(effectiveDistance,
+					   getExternalSubsystems().m_config->getSceneReflectionProbeShadowEffectiveDistance()));
 
 			// Add something to avoid complains
 			frc.setLodDistances(

+ 3 - 3
AnKi/Scene/ModelNode.cpp

@@ -307,13 +307,13 @@ void ModelNode::draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData
 
 			cmdb->setVertexAttribute(attribLocation, bufferBinding, fmt, relativeOffset);
 
-			cmdb->bindVertexBuffer(bufferBinding, getUnifiedGeometryMemoryPool().getBuffer(),
+			cmdb->bindVertexBuffer(bufferBinding, getExternalSubsystems().m_unifiedGeometryMemPool->getBuffer(),
 								   modelInf.m_vertexBufferOffsets[streamId], vertexStride, VertexStepRate::kVertex);
 		}
 
 		// Bind index buffer
-		cmdb->bindIndexBuffer(getUnifiedGeometryMemoryPool().getBuffer(), modelInf.m_indexBufferOffset,
-							  IndexType::kU16);
+		cmdb->bindIndexBuffer(getExternalSubsystems().m_unifiedGeometryMemPool->getBuffer(),
+							  modelInf.m_indexBufferOffset, IndexType::kU16);
 
 		// Draw
 		cmdb->drawElements(PrimitiveTopology::kTriangles, modelInf.m_indexCount, instanceCount, modelInf.m_firstIndex,

+ 1 - 1
AnKi/Scene/PhysicsDebugNode.cpp

@@ -38,7 +38,7 @@ void PhysicsDebugNode::draw(RenderQueueDrawContext& ctx)
 	if(ctx.m_debugDraw)
 	{
 		m_physDbgDrawer.start(ctx.m_viewProjectionMatrix, ctx.m_commandBuffer, ctx.m_stagingGpuAllocator);
-		m_physDbgDrawer.drawWorld(getSceneGraph().getPhysicsWorld());
+		m_physDbgDrawer.drawWorld(*getExternalSubsystems().m_physicsWorld);
 		m_physDbgDrawer.end();
 	}
 }

+ 2 - 2
AnKi/Scene/PlayerNode.cpp

@@ -29,7 +29,7 @@ public:
 		updated = false;
 
 		PlayerControllerComponent& playerc = info.m_node->getFirstComponentOfType<PlayerControllerComponent>();
-		const Input& in = info.m_node->getSceneGraph().getInput();
+		const Input& in = *getExternalSubsystems(*info.m_node).m_input;
 		const F32 ang = toRad(7.0f);
 
 		F32 y = in.getMousePosition().y();
@@ -81,7 +81,7 @@ public:
 
 		PlayerControllerComponent& playerc = info.m_node->getFirstComponentOfType<PlayerControllerComponent>();
 		MoveComponent& move = info.m_node->getFirstComponentOfType<MoveComponent>();
-		const Input& in = info.m_node->getSceneGraph().getInput();
+		const Input& in = *getExternalSubsystems(*info.m_node).m_input;
 
 		const F32 speed = 0.5;
 

+ 4 - 2
AnKi/Scene/ReflectionProbeNode.cpp

@@ -155,13 +155,15 @@ void ReflectionProbeNode::onShapeUpdate(ReflectionProbeComponent& reflc)
 	const Vec3 halfProbeSize = reflc.getBoxVolumeSize() / 2.0f;
 	F32 effectiveDistance = max(halfProbeSize.x(), halfProbeSize.y());
 	effectiveDistance = max(effectiveDistance, halfProbeSize.z());
-	effectiveDistance = max(effectiveDistance, getConfig().getSceneReflectionProbeEffectiveDistance());
+	effectiveDistance =
+		max(effectiveDistance, getExternalSubsystems().m_config->getSceneReflectionProbeEffectiveDistance());
 
 	// Update frustum components
 	iterateComponentsOfType<FrustumComponent>([&](FrustumComponent& frc) {
 		frc.setFar(effectiveDistance);
 		frc.setShadowCascadeDistance(
-			0, min(effectiveDistance, getConfig().getSceneReflectionProbeShadowEffectiveDistance()));
+			0,
+			min(effectiveDistance, getExternalSubsystems().m_config->getSceneReflectionProbeShadowEffectiveDistance()));
 
 		// Add something to avoid complains
 		frc.setLodDistances(

+ 12 - 24
AnKi/Scene/SceneGraph.cpp

@@ -52,29 +52,17 @@ SceneGraph::~SceneGraph()
 	}
 }
 
-Error SceneGraph::init(AllocAlignedCallback allocCb, void* allocCbData, ThreadHive* threadHive,
-					   ResourceManager* resources, Input* input, ScriptManager* scriptManager, UiManager* uiManager,
-					   ConfigSet* config, const Timestamp* globalTimestamp,
-					   UnifiedGeometryMemoryPool* unifiedGeometryMemPool)
+Error SceneGraph::init(const SceneGraphInitInfo& initInfo)
 {
-	m_globalTimestamp = globalTimestamp;
-	m_threadHive = threadHive;
-	m_resources = resources;
-	m_gr = &m_resources->getGrManager();
-	m_physics = &m_resources->getPhysicsWorld();
-	m_input = input;
-	m_scriptManager = scriptManager;
-	m_uiManager = uiManager;
-	m_config = config;
-	m_unifiedGeometryMemPool = unifiedGeometryMemPool;
-
-	m_pool.init(allocCb, allocCbData);
-	m_framePool.init(allocCb, allocCbData, 1 * 1024 * 1024);
+	m_subsystems = initInfo;
+
+	m_pool.init(initInfo.m_allocCallback, initInfo.m_allocCallbackData);
+	m_framePool.init(initInfo.m_allocCallback, initInfo.m_allocCallbackData, 1 * 1024 * 1024);
 
 	ANKI_CHECK(m_events.init(this));
 
 	m_octree = newInstance<Octree>(m_pool, &m_pool);
-	m_octree->init(m_sceneMin, m_sceneMax, m_config->getSceneOctreeMaxDepth());
+	m_octree->init(m_sceneMin, m_sceneMax, m_subsystems.m_config->getSceneOctreeMaxDepth());
 
 	// Init the default main camera
 	ANKI_CHECK(newSceneNode<PerspectiveCameraNode>("mainCamera", m_defaultMainCam));
@@ -87,7 +75,7 @@ Error SceneGraph::init(AllocAlignedCallback allocCb, void* allocCbData, ThreadHi
 	ANKI_CHECK(newSceneNode<PhysicsDebugNode>("_physicsDebugNode", pnode));
 
 	// Other
-	ANKI_CHECK(m_debugDrawer.init(&getResourceManager()));
+	ANKI_CHECK(m_debugDrawer.init(m_subsystems.m_resourceManager, m_subsystems.m_grManager));
 
 	return Error::kNone;
 }
@@ -183,7 +171,7 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 
 	m_stats.m_updateTime = HighRezTimer::getCurrentTime();
 
-	m_timestamp = *m_globalTimestamp;
+	m_timestamp = *m_subsystems.m_globalTimestamp;
 	ANKI_ASSERT(m_timestamp > 0);
 
 	// Reset the framepool
@@ -201,7 +189,7 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 	{
 		ANKI_TRACE_SCOPED_EVENT(SCENE_PHYSICS_UPDATE);
 		m_stats.m_physicsUpdate = HighRezTimer::getCurrentTime();
-		m_physics->update(crntTime - prevUpdateTime);
+		m_subsystems.m_physicsWorld->update(crntTime - prevUpdateTime);
 		m_stats.m_physicsUpdate = HighRezTimer::getCurrentTime() - m_stats.m_physicsUpdate;
 	}
 
@@ -217,7 +205,7 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 		updateCtx.m_prevUpdateTime = prevUpdateTime;
 		updateCtx.m_crntTime = crntTime;
 
-		for(U i = 0; i < m_threadHive->getThreadCount(); i++)
+		for(U i = 0; i < m_subsystems.m_threadHive->getThreadCount(); i++)
 		{
 			tasks[i] = ANKI_THREAD_HIVE_TASK(
 				{
@@ -229,8 +217,8 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 				&updateCtx, nullptr, nullptr);
 		}
 
-		m_threadHive->submitTasks(&tasks[0], m_threadHive->getThreadCount());
-		m_threadHive->waitAllTasks();
+		m_subsystems.m_threadHive->submitTasks(&tasks[0], m_subsystems.m_threadHive->getThreadCount());
+		m_subsystems.m_threadHive->waitAllTasks();
 	}
 
 	m_stats.m_updateTime = HighRezTimer::getCurrentTime() - m_stats.m_updateTime;

+ 11 - 68
AnKi/Scene/SceneGraph.h

@@ -17,14 +17,9 @@
 namespace anki {
 
 // Forward
-class ResourceManager;
 class CameraNode;
-class Input;
-class ConfigSet;
-class PerspectiveCameraNode;
 class Octree;
-class UiManager;
-class UnifiedGeometryMemoryPool;
+class PerspectiveCameraNode;
 
 /// @addtogroup scene
 /// @{
@@ -38,20 +33,26 @@ public:
 	Second m_physicsUpdate ANKI_DEBUG_CODE(= 0.0);
 };
 
+class SceneGraphInitInfo : public SceneGraphExternalSubsystems
+{
+public:
+	AllocAlignedCallback m_allocCallback = nullptr;
+	void* m_allocCallbackData = nullptr;
+};
+
 /// The scene graph that  all the scene entities
 class SceneGraph
 {
 	friend class SceneNode;
 	friend class UpdateSceneNodesTask;
+	friend class Event;
 
 public:
 	SceneGraph();
 
 	~SceneGraph();
 
-	Error init(AllocAlignedCallback allocCb, void* allocCbData, ThreadHive* threadHive, ResourceManager* resources,
-			   Input* input, ScriptManager* scriptManager, UiManager* uiManager, ConfigSet* config,
-			   const Timestamp* globalTimestamp, UnifiedGeometryMemoryPool* unifiedGeometryMemPool);
+	Error init(const SceneGraphInitInfo& initInfo);
 
 	Timestamp getGlobalTimestamp() const
 	{
@@ -101,11 +102,6 @@ public:
 		return m_events;
 	}
 
-	ThreadHive& getThreadHive()
-	{
-		return *m_threadHive;
-	}
-
 	Error update(Second prevUpdateTime, Second crntTime);
 
 	void doVisibilityTests(RenderQueue& rqueue);
@@ -163,43 +159,6 @@ public:
 		return m_sceneMax;
 	}
 
-	ResourceManager& getResourceManager()
-	{
-		return *m_resources;
-	}
-
-	GrManager& getGrManager()
-	{
-		return *m_gr;
-	}
-
-	PhysicsWorld& getPhysicsWorld()
-	{
-		return *m_physics;
-	}
-
-	ScriptManager& getScriptManager()
-	{
-		ANKI_ASSERT(m_scriptManager);
-		return *m_scriptManager;
-	}
-
-	const PhysicsWorld& getPhysicsWorld() const
-	{
-		return *m_physics;
-	}
-
-	const Input& getInput() const
-	{
-		ANKI_ASSERT(m_input);
-		return *m_input;
-	}
-
-	UiManager& getUiManager()
-	{
-		return *m_uiManager;
-	}
-
 	U64 getNewUuid()
 	{
 		return m_nodesUuid.fetchAdd(1);
@@ -216,28 +175,12 @@ public:
 		return m_debugDrawer;
 	}
 
-	ANKI_INTERNAL const ConfigSet& getConfig()
-	{
-		ANKI_ASSERT(m_config);
-		return *m_config;
-	}
-
 private:
 	class UpdateSceneNodesCtx;
 
-	const Timestamp* m_globalTimestamp = nullptr;
 	Timestamp m_timestamp = 0; ///< Cached timestamp
 
-	// Sub-systems
-	ThreadHive* m_threadHive = nullptr;
-	ResourceManager* m_resources = nullptr;
-	GrManager* m_gr = nullptr;
-	PhysicsWorld* m_physics = nullptr;
-	Input* m_input = nullptr;
-	ScriptManager* m_scriptManager = nullptr;
-	UiManager* m_uiManager = nullptr;
-	ConfigSet* m_config = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGeometryMemPool = nullptr;
+	SceneGraphExternalSubsystems m_subsystems;
 
 	mutable HeapMemoryPool m_pool;
 	mutable StackMemoryPool m_framePool;

+ 2 - 12
AnKi/Scene/SceneNode.cpp

@@ -67,19 +67,9 @@ StackMemoryPool& SceneNode::getFrameMemoryPool() const
 	return m_scene->getFrameMemoryPool();
 }
 
-ResourceManager& SceneNode::getResourceManager()
+SceneGraphExternalSubsystems& SceneNode::getExternalSubsystems() const
 {
-	return m_scene->getResourceManager();
-}
-
-const ConfigSet& SceneNode::getConfig() const
-{
-	return m_scene->getConfig();
-}
-
-const UnifiedGeometryMemoryPool& SceneNode::getUnifiedGeometryMemoryPool() const
-{
-	return *m_scene->m_unifiedGeometryMemPool;
+	return m_scene->m_subsystems;
 }
 
 } // end namespace anki

+ 6 - 10
AnKi/Scene/SceneNode.h

@@ -15,9 +15,7 @@
 namespace anki {
 
 // Forward
-class ResourceManager;
-class ConfigSet;
-class UnifiedGeometryMemoryPool;
+class SceneGraphExternalSubsystems;
 
 /// @addtogroup scene
 /// @{
@@ -25,6 +23,8 @@ class UnifiedGeometryMemoryPool;
 /// Interface class backbone of scene
 class SceneNode : public Hierarchy<SceneNode>, public IntrusiveListEnabled<SceneNode>
 {
+	friend class SceneComponent;
+
 public:
 	using Base = Hierarchy<SceneNode>;
 
@@ -52,9 +52,7 @@ public:
 		return *m_scene;
 	}
 
-	const ConfigSet& getConfig() const;
-
-	/// Return the name. It may be empty for nodes that we don't want to track
+	/// Return the name. It may be empty for nodes that we don't want to track.
 	CString getName() const
 	{
 		return (!m_name.isEmpty()) ? m_name.toCString() : CString();
@@ -74,8 +72,6 @@ public:
 
 	Timestamp getGlobalTimestamp() const;
 
-	const UnifiedGeometryMemoryPool& getUnifiedGeometryMemoryPool() const;
-
 	Timestamp getComponentMaxTimestamp() const
 	{
 		return m_maxComponentTimestamp;
@@ -264,6 +260,8 @@ public:
 	}
 
 protected:
+	SceneGraphExternalSubsystems& getExternalSubsystems() const;
+
 	/// Create and append a component to the components container. The SceneNode has the ownership.
 	template<typename TComponent>
 	TComponent* newComponent()
@@ -274,8 +272,6 @@ protected:
 		return comp;
 	}
 
-	ResourceManager& getResourceManager();
-
 private:
 	/// This class packs a few info used by components.
 	class ComponentsArrayElement

+ 2 - 2
AnKi/Scene/Visibility.cpp

@@ -838,11 +838,11 @@ void SceneGraph::doVisibilityTests(SceneNode& fsn, SceneGraph& scene, RenderQueu
 {
 	ANKI_TRACE_SCOPED_EVENT(SCENE_VIS_TESTS);
 
-	ThreadHive& hive = scene.getThreadHive();
+	ThreadHive& hive = *scene.m_subsystems.m_threadHive;
 
 	VisibilityContext ctx;
 	ctx.m_scene = &scene;
-	ctx.m_earlyZDist = scene.getConfig().getSceneEarlyZDistance();
+	ctx.m_earlyZDist = scene.m_subsystems.m_config->getSceneEarlyZDistance();
 	const FrustumComponent& mainFrustum = fsn.getFirstComponentOfType<FrustumComponent>();
 	ctx.submitNewWork(mainFrustum, mainFrustum, rqueue, hive);
 

+ 8 - 8
AnKi/Ui/Canvas.cpp

@@ -36,7 +36,7 @@ Error Canvas::init(FontPtr font, U32 fontHeight, U32 width, U32 height)
 	resize(width, height);
 
 	// Create program
-	ANKI_CHECK(m_manager->getResourceManager().loadResource("ShaderBinaries/Ui.ankiprogbin", m_prog));
+	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource("ShaderBinaries/Ui.ankiprogbin", m_prog));
 
 	for(U32 i = 0; i < kShaderCount; ++i)
 	{
@@ -52,11 +52,11 @@ Error Canvas::init(FontPtr font, U32 fontHeight, U32 width, U32 height)
 	samplerInit.m_minMagFilter = SamplingFilter::kLinear;
 	samplerInit.m_mipmapFilter = SamplingFilter::kLinear;
 	samplerInit.m_addressing = SamplingAddressing::kRepeat;
-	m_linearLinearRepeatSampler = m_manager->getGrManager().newSampler(samplerInit);
+	m_linearLinearRepeatSampler = getExternalSubsystems().m_grManager->newSampler(samplerInit);
 
 	samplerInit.m_minMagFilter = SamplingFilter::kNearest;
 	samplerInit.m_mipmapFilter = SamplingFilter::kNearest;
-	m_nearestNearestRepeatSampler = m_manager->getGrManager().newSampler(samplerInit);
+	m_nearestNearestRepeatSampler = getExternalSubsystems().m_grManager->newSampler(samplerInit);
 
 	// Allocator
 	m_tempPool.init(getMemoryPool().getAllocationCallback(), getMemoryPool().getAllocationCallbackUserData(), 512_B);
@@ -104,7 +104,7 @@ Error Canvas::init(FontPtr font, U32 fontHeight, U32 width, U32 height)
 
 void Canvas::handleInput()
 {
-	const Input& in = m_manager->getInput();
+	const Input& in = *getExternalSubsystems().m_input;
 
 	// Begin
 	setImAllocator();
@@ -216,10 +216,10 @@ void Canvas::appendToCommandBufferInternal(CommandBufferPtr& cmdb)
 			return;
 		}
 
-		ImDrawVert* verts = static_cast<ImDrawVert*>(
-			m_manager->getStagingGpuMemory().allocateFrame(verticesSize, StagingGpuMemoryType::kVertex, vertsToken));
-		ImDrawIdx* indices = static_cast<ImDrawIdx*>(
-			m_manager->getStagingGpuMemory().allocateFrame(indicesSize, StagingGpuMemoryType::kVertex, indicesToken));
+		ImDrawVert* verts = static_cast<ImDrawVert*>(getExternalSubsystems().m_stagingGpuMemoryPool->allocateFrame(
+			verticesSize, StagingGpuMemoryType::kVertex, vertsToken));
+		ImDrawIdx* indices = static_cast<ImDrawIdx*>(getExternalSubsystems().m_stagingGpuMemoryPool->allocateFrame(
+			indicesSize, StagingGpuMemoryType::kVertex, indicesToken));
 
 		for(I n = 0; n < drawData.CmdListsCount; ++n)
 		{

+ 15 - 0
AnKi/Ui/Common.h

@@ -16,6 +16,11 @@ namespace anki {
 
 // Forward
 class UiManager;
+class ResourceManager;
+class GrManager;
+class StagingGpuMemoryPool;
+class Input;
+class ResourceFilesystem;
 
 /// @addtogroup ui
 /// @{
@@ -34,6 +39,16 @@ ANKI_UI_OBJECT_FW(Canvas)
 ANKI_UI_OBJECT_FW(UiImmediateModeBuilder)
 #undef ANKI_UI_OBJECT
 
+class UiExternalSubsystems
+{
+public:
+	ResourceManager* m_resourceManager = nullptr;
+	ResourceFilesystem* m_resourceFilesystem = nullptr;
+	GrManager* m_grManager = nullptr;
+	StagingGpuMemoryPool* m_stagingGpuMemoryPool = nullptr;
+	Input* m_input = nullptr;
+};
+
 inline Vec2 toAnki(const ImVec2& v)
 {
 	return Vec2(v.x, v.y);

+ 6 - 6
AnKi/Ui/Font.cpp

@@ -31,7 +31,7 @@ Error Font::init(const CString& filename, ConstWeakArray<U32> fontHeights)
 
 	// Load font in memory
 	ResourceFilePtr file;
-	ANKI_CHECK(m_manager->getResourceManager().getFilesystem().openFile(filename, file));
+	ANKI_CHECK(getExternalSubsystems().m_resourceFilesystem->openFile(filename, file));
 	m_fontData.create(getMemoryPool(), U32(file->getSize()));
 	ANKI_CHECK(file->read(&m_fontData[0], file->getSize()));
 
@@ -70,7 +70,7 @@ void Font::createTexture(const void* data, U32 width, U32 height)
 
 	// Create and populate the buffer
 	const U32 buffSize = width * height * 4;
-	BufferPtr buff = m_manager->getGrManager().newBuffer(
+	BufferPtr buff = getExternalSubsystems().m_grManager->newBuffer(
 		BufferInitInfo(buffSize, BufferUsageBit::kTransferSource, BufferMapAccessBit::kWrite, "UI"));
 	void* mapped = buff->map(0, buffSize, BufferMapAccessBit::kWrite);
 	memcpy(mapped, data, buffSize);
@@ -86,20 +86,20 @@ void Font::createTexture(const void* data, U32 width, U32 height)
 		TextureUsageBit::kTransferDestination | TextureUsageBit::kSampledFragment | TextureUsageBit::kGenerateMipmaps;
 	texInit.m_mipmapCount = 1; // No mips because it will appear blurry with trilinear filtering
 
-	m_tex = m_manager->getGrManager().newTexture(texInit);
+	m_tex = getExternalSubsystems().m_grManager->newTexture(texInit);
 
 	// Create the whole texture view
-	m_texView = m_manager->getGrManager().newTextureView(TextureViewInitInfo(m_tex, "Font"));
+	m_texView = getExternalSubsystems().m_grManager->newTextureView(TextureViewInitInfo(m_tex, "Font"));
 	m_imFontAtlas->SetTexID(UiImageId(m_texView));
 
 	// Do the copy
 	constexpr TextureSurfaceInfo surf(0, 0, 0, 0);
 	CommandBufferInitInfo cmdbInit;
 	cmdbInit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
-	CommandBufferPtr cmdb = m_manager->getGrManager().newCommandBuffer(cmdbInit);
+	CommandBufferPtr cmdb = getExternalSubsystems().m_grManager->newCommandBuffer(cmdbInit);
 
 	TextureViewInitInfo viewInit(m_tex, surf, DepthStencilAspectBit::kNone, "TempFont");
-	TextureViewPtr tmpView = m_manager->getGrManager().newTextureView(viewInit);
+	TextureViewPtr tmpView = getExternalSubsystems().m_grManager->newTextureView(viewInit);
 
 	TextureBarrierInfo barrier = {m_tex.get(), TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, surf};
 	cmdb->setPipelineBarrier({&barrier, 1}, {}, {});

+ 3 - 13
AnKi/Ui/UiManager.cpp

@@ -17,20 +17,10 @@ UiManager::~UiManager()
 {
 }
 
-Error UiManager::init(AllocAlignedCallback allocCallback, void* allocCallbackUserData, ResourceManager* resources,
-					  GrManager* gr, StagingGpuMemoryPool* gpuMem, Input* input)
+Error UiManager::init(UiManagerInitInfo& initInfo)
 {
-	ANKI_ASSERT(resources);
-	ANKI_ASSERT(gr);
-	ANKI_ASSERT(gpuMem);
-	ANKI_ASSERT(input);
-
-	m_pool.init(allocCallback, allocCallbackUserData);
-	m_resources = resources;
-	m_gr = gr;
-	m_gpuMem = gpuMem;
-	m_input = input;
-
+	m_pool.init(initInfo.m_allocCallback, initInfo.m_allocCallbackUserData);
+	m_subsystems = initInfo;
 	return Error::kNone;
 }
 

+ 11 - 36
AnKi/Ui/UiManager.h

@@ -9,55 +9,33 @@
 
 namespace anki {
 
-// Forward
-class ResourceManager;
-class GrManager;
-class StagingGpuMemoryPool;
-class Input;
-
 /// @addtogroup ui
 /// @{
 
+class UiManagerInitInfo : public UiExternalSubsystems
+{
+public:
+	AllocAlignedCallback m_allocCallback = nullptr;
+	void* m_allocCallbackUserData = nullptr;
+};
+
 /// UI manager.
 class UiManager
 {
+	friend class UiObject;
+
 public:
 	UiManager();
 
 	~UiManager();
 
-	Error init(AllocAlignedCallback allocCallback, void* allocCallbackUserData, ResourceManager* resources,
-			   GrManager* gr, StagingGpuMemoryPool* gpuMem, Input* input);
+	Error init(UiManagerInitInfo& initInfo);
 
 	HeapMemoryPool& getMemoryPool() const
 	{
 		return m_pool;
 	}
 
-	ResourceManager& getResourceManager()
-	{
-		ANKI_ASSERT(m_resources);
-		return *m_resources;
-	}
-
-	GrManager& getGrManager()
-	{
-		ANKI_ASSERT(m_gr);
-		return *m_gr;
-	}
-
-	StagingGpuMemoryPool& getStagingGpuMemory()
-	{
-		ANKI_ASSERT(m_gpuMem);
-		return *m_gpuMem;
-	}
-
-	const Input& getInput() const
-	{
-		ANKI_ASSERT(m_input);
-		return *m_input;
-	}
-
 	/// Create a new UI object.
 	template<typename T, typename Y, typename... Args>
 	Error newInstance(IntrusivePtr<Y>& ptr, Args&&... args)
@@ -77,10 +55,7 @@ public:
 
 private:
 	mutable HeapMemoryPool m_pool;
-	ResourceManager* m_resources = nullptr;
-	GrManager* m_gr = nullptr;
-	StagingGpuMemoryPool* m_gpuMem = nullptr;
-	Input* m_input = nullptr;
+	UiExternalSubsystems m_subsystems;
 };
 /// @}
 

+ 5 - 0
AnKi/Ui/UiObject.cpp

@@ -13,4 +13,9 @@ HeapMemoryPool& UiObject::getMemoryPool() const
 	return m_manager->getMemoryPool();
 }
 
+UiExternalSubsystems& UiObject::getExternalSubsystems() const
+{
+	return m_manager->m_subsystems;
+}
+
 } // end namespace anki

+ 2 - 0
AnKi/Ui/UiObject.h

@@ -66,6 +66,8 @@ public:
 protected:
 	UiManager* m_manager;
 	mutable Atomic<I32> m_refcount = {0};
+
+	UiExternalSubsystems& getExternalSubsystems() const;
 };
 /// @}
 

+ 3 - 3
Tests/Framework/Framework.cpp

@@ -290,9 +290,9 @@ ResourceManager* createResourceManager(ConfigSet* cfg, GrManager* gr, PhysicsWor
 	ANKI_TEST_EXPECT_NO_ERR(resourceFs->init(*cfg, allocAligned, nullptr));
 
 	ResourceManagerInitInfo rinit;
-	rinit.m_gr = gr;
-	rinit.m_physics = physics;
-	rinit.m_resourceFs = resourceFs;
+	rinit.m_grManager = gr;
+	rinit.m_physicsWorld = physics;
+	rinit.m_resourceFilesystem = resourceFs;
 	rinit.m_config = cfg;
 	rinit.m_allocCallback = allocAligned;
 	rinit.m_allocCallbackData = nullptr;

+ 1 - 1
Tests/Resource/ResourceManager.cpp

@@ -16,7 +16,7 @@ ANKI_TEST(Resource, ResourceManager)
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 
 	ResourceManagerInitInfo rinit;
-	rinit.m_gr = nullptr;
+	rinit.m_grManager = nullptr;
 	rinit.m_config = &config;
 	rinit.m_allocCallback = allocAligned;
 	rinit.m_allocCallbackData = nullptr;

+ 9 - 1
Tests/Ui/Ui.cpp

@@ -78,7 +78,15 @@ ANKI_TEST(Ui, Ui)
 	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(gr, cfg));
 
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
-	ANKI_TEST_EXPECT_NO_ERR(ui->init(allocAligned, nullptr, resource, gr, stagingMem, in));
+	UiManagerInitInfo uiInitInfo;
+	uiInitInfo.m_allocCallback = allocAligned;
+	uiInitInfo.m_allocCallbackUserData = nullptr;
+	uiInitInfo.m_grManager = gr;
+	uiInitInfo.m_input = in;
+	uiInitInfo.m_resourceFilesystem = fs;
+	uiInitInfo.m_resourceManager = resource;
+	uiInitInfo.m_stagingGpuMemoryPool = stagingMem;
+	ANKI_TEST_EXPECT_NO_ERR(ui->init(uiInitInfo));
 
 	{
 		FontPtr font;

+ 4 - 4
Tools/Image/ImageViewerMain.cpp

@@ -25,10 +25,10 @@ public:
 			},
 			this);
 
-		ANKI_CHECK_AND_IGNORE(getSceneGraph().getUiManager().newInstance(m_font, "EngineAssets/UbuntuMonoRegular.ttf",
-																		 Array<U32, 1>{16}));
+		ANKI_CHECK_AND_IGNORE(getExternalSubsystems().m_uiManager->newInstance(
+			m_font, "EngineAssets/UbuntuMonoRegular.ttf", Array<U32, 1>{16}));
 
-		ANKI_CHECK_AND_IGNORE(getSceneGraph().getResourceManager().loadResource(
+		ANKI_CHECK_AND_IGNORE(getExternalSubsystems().m_resourceManager->loadResource(
 			"ShaderBinaries/UiVisualizeImage.ankiprogbin", m_imageProgram));
 	}
 
@@ -152,7 +152,7 @@ private:
 				TextureViewInitInfo viewInitInf(m_imageResource->getTexture());
 				viewInitInf.m_firstMipmap = m_crntMip;
 				viewInitInf.m_mipmapCount = 1;
-				m_textureView = getSceneGraph().getGrManager().newTextureView(viewInitInf);
+				m_textureView = getExternalSubsystems().m_grManager->newTextureView(viewInitInf);
 			}
 
 			ImGui::SameLine();