Skip to content

Commit 998eb40

Browse files
committed
decouple SceneBuilder from AssImp
* use AbstractFactory pattern to deliver family of classes specific for chosen Importer * use existing AssImp Importer as a default one if no specializations available Signed-off-by: Mateusz Żak <[email protected]>
1 parent fd246cc commit 998eb40

16 files changed

+695
-85
lines changed

Code/Tools/SceneAPI/SceneBuilder/DllMain.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,30 @@
88

99
#if !defined(AZ_MONOLITHIC_BUILD)
1010

11+
#include "ImportContexts/AssImpImportContextProvider.h"
12+
#include "SceneBuilderSystemComponent.h"
13+
1114
#include <AzCore/Component/Component.h>
1215
#include <AzCore/Component/ComponentApplicationBus.h>
13-
#include <AzCore/std/containers/vector.h>
1416
#include <AzCore/Module/Environment.h>
17+
#include <AzCore/std/containers/vector.h>
18+
#include <SceneAPI/SceneBuilder/ImportContextRegistry.h>
1519
#include <SceneAPI/SceneBuilder/SceneImportRequestHandler.h>
1620

17-
#include <SceneAPI/SceneBuilder/SceneImporter.h>
21+
#include <SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.h>
1822
#include <SceneAPI/SceneBuilder/Importers/AssImpBitangentStreamImporter.h>
23+
#include <SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.h>
24+
#include <SceneAPI/SceneBuilder/Importers/AssImpBoneImporter.h>
1925
#include <SceneAPI/SceneBuilder/Importers/AssImpColorStreamImporter.h>
2026
#include <SceneAPI/SceneBuilder/Importers/AssImpCustomPropertyImporter.h>
2127
#include <SceneAPI/SceneBuilder/Importers/AssImpMaterialImporter.h>
2228
#include <SceneAPI/SceneBuilder/Importers/AssImpMeshImporter.h>
29+
#include <SceneAPI/SceneBuilder/Importers/AssImpSkinImporter.h>
30+
#include <SceneAPI/SceneBuilder/Importers/AssImpSkinWeightsImporter.h>
2331
#include <SceneAPI/SceneBuilder/Importers/AssImpTangentStreamImporter.h>
2432
#include <SceneAPI/SceneBuilder/Importers/AssImpTransformImporter.h>
2533
#include <SceneAPI/SceneBuilder/Importers/AssImpUvMapImporter.h>
26-
#include <SceneAPI/SceneBuilder/Importers/AssImpSkinImporter.h>
27-
#include <SceneAPI/SceneBuilder/Importers/AssImpSkinWeightsImporter.h>
28-
#include <SceneAPI/SceneBuilder/Importers/AssImpBoneImporter.h>
29-
#include <SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.h>
30-
#include <SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.h>
34+
#include <SceneAPI/SceneBuilder/SceneImporter.h>
3135

3236
namespace AZ
3337
{
@@ -50,6 +54,9 @@ namespace AZ
5054
g_componentDescriptors.push_back(SceneBuilder::SceneImporter::CreateDescriptor());
5155
g_componentDescriptors.push_back(SceneImportRequestHandler::CreateDescriptor());
5256

57+
// ImportContextProviderRegistry
58+
g_componentDescriptors.push_back(SceneBuilderSystemComponent::CreateDescriptor());
59+
5360
// Node and attribute importers
5461
g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor());
5562
g_componentDescriptors.push_back(AssImpColorStreamImporter::CreateDescriptor());
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
#pragma once
9+
10+
#include <AzCore/Interface/Interface.h>
11+
#include <AzCore/Memory/SystemAllocator.h>
12+
#include <AzCore/RTTI/RTTI.h>
13+
#include <AzCore/std/smart_ptr/unique_ptr.h>
14+
15+
namespace AZ
16+
{
17+
namespace SceneAPI
18+
{
19+
namespace SceneBuilder
20+
{
21+
struct ImportContextProvider;
22+
23+
// ImportContextRegistry realizes Abstract Factory Pattern.
24+
// It provides a family of objects related to a particular Import Context.
25+
// Those include ImportContext specializations for different stages of the Import pipeline
26+
// as well as Scene and Node wrappers.
27+
// To add a new library for importing scene assets:
28+
// - specialize and implement the ImportContextProvider
29+
// - register specialization with this interface
30+
class ImportContextRegistry
31+
{
32+
public:
33+
AZ_RTTI(ImportContextRegistry, "{5faaaa8a-2497-41d7-8b5c-5af4390af776}");
34+
AZ_CLASS_ALLOCATOR(ImportContextRegistry, AZ::SystemAllocator, 0);
35+
36+
virtual ~ImportContextRegistry() = default;
37+
38+
virtual void RegisterContextProvider(ImportContextProvider* provider) = 0;
39+
virtual void UnregisterContextProvider(ImportContextProvider* provider) = 0;
40+
virtual ImportContextProvider* SelectImportProvider(AZStd::string_view fileExtension) const = 0;
41+
};
42+
43+
using ImportContextRegistryInterface = AZ::Interface<ImportContextRegistry>;
44+
} // namespace SceneBuilder
45+
} // namespace SceneAPI
46+
} // namespace AZ
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#include "ImportContextRegistryManager.h"
10+
11+
namespace AZ
12+
{
13+
namespace SceneAPI
14+
{
15+
namespace SceneBuilder
16+
{
17+
ImportContextRegistryManager::ImportContextRegistryManager()
18+
{
19+
// register AssImp default provider
20+
auto assimpContextProvider = aznew AssImpImportContextProvider();
21+
m_importContextProviders.push_back(AZStd::unique_ptr<ImportContextProvider>(assimpContextProvider));
22+
};
23+
24+
void ImportContextRegistryManager::RegisterContextProvider(ImportContextProvider* provider)
25+
{
26+
if (provider)
27+
{
28+
m_importContextProviders.push_back(AZStd::unique_ptr<ImportContextProvider>(provider));
29+
}
30+
}
31+
32+
void ImportContextRegistryManager::UnregisterContextProvider(ImportContextProvider* provider)
33+
{
34+
AZ_TracePrintf("SceneAPI", "Unregistered ImportContextProvider %s", provider->GetImporterName().data());
35+
for (auto it = m_importContextProviders.begin(); it != m_importContextProviders.end(); ++it)
36+
{
37+
if (it->get() == provider)
38+
{
39+
m_importContextProviders.erase(it);
40+
break; // Assuming only one instance can be registered at a time
41+
}
42+
}
43+
}
44+
45+
ImportContextProvider* ImportContextRegistryManager::SelectImportProvider(AZStd::string_view fileExtension) const
46+
{
47+
AZ_TracePrintf(
48+
"SceneAPI",
49+
"Finding ImportContextProvider (registered %d) suitable for extension: %.*s",
50+
m_importContextProviders.size(),
51+
static_cast<int>(fileExtension.length()),
52+
fileExtension.data());
53+
// search in reverse order since the default AssImp Provider can handle all extenstions
54+
for (auto it = m_importContextProviders.rbegin(); it != m_importContextProviders.rend(); ++it)
55+
{
56+
if (it->get()->CanHandleExtension(fileExtension))
57+
{
58+
return it->get();
59+
}
60+
else
61+
{
62+
AZ_TracePrintf(
63+
"SceneAPI",
64+
"Importer %s cannot handle %.*s",
65+
it->get()->GetImporterName().data(),
66+
static_cast<int>(fileExtension.length()),
67+
fileExtension.data());
68+
}
69+
}
70+
return nullptr; // No provider found
71+
}
72+
73+
} // namespace SceneBuilder
74+
} // namespace SceneAPI
75+
} // namespace AZ
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#pragma once
10+
#include <SceneAPI/SceneBuilder/ImportContextRegistry.h>
11+
#include <AzCore/Debug/Trace.h>
12+
#include <AzCore/std/containers/vector.h>
13+
#include <SceneAPI/SceneBuilder/ImportContexts/ImportContextProvider.h>
14+
15+
namespace AZ
16+
{
17+
namespace SceneAPI
18+
{
19+
namespace SceneBuilder
20+
{
21+
// Implementation of the ImportContextRegistryInterface.
22+
class ImportContextRegistryManager : public ImportContextRegistryInterface::Registrar
23+
{
24+
public:
25+
AZ_RTTI(ImportContextRegistryManager, "{d3107473-4f99-4421-b4a8-ece66a922191}", ImportContextRegistry);
26+
AZ_CLASS_ALLOCATOR(ImportContextRegistryManager, AZ::SystemAllocator, 0);
27+
28+
ImportContextRegistryManager();
29+
ImportContextRegistryManager(const ImportContextRegistryManager&) = delete;
30+
ImportContextRegistryManager& operator=(const ImportContextRegistryManager&) = delete;
31+
32+
~ImportContextRegistryManager() override = default;
33+
34+
void RegisterContextProvider(ImportContextProvider* provider) override;
35+
void UnregisterContextProvider(ImportContextProvider* provider) override;
36+
ImportContextProvider* SelectImportProvider(AZStd::string_view fileExtension) const override;
37+
38+
private:
39+
AZStd::vector<AZStd::unique_ptr<ImportContextProvider>> m_importContextProviders;
40+
};
41+
} // namespace SceneBuilder
42+
} // namespace SceneAPI
43+
} // namespace AZ
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#include "AssImpImportContextProvider.h"
10+
#include <SceneAPI/SceneBuilder/ImportContexts/AssImpImportContexts.h>
11+
12+
namespace AZ
13+
{
14+
namespace SceneAPI
15+
{
16+
namespace SceneBuilder
17+
{
18+
AZStd::shared_ptr<NodeEncounteredContextBase> AssImpImportContextProvider::CreateNodeEncounteredContext(
19+
Containers::Scene& scene,
20+
Containers::SceneGraph::NodeIndex currentGraphPosition,
21+
const SceneSystem& sourceSceneSystem,
22+
RenamedNodesMap& nodeNameMap,
23+
SDKScene::SceneWrapperBase& sourceScene,
24+
SDKNode::NodeWrapper& sourceNode)
25+
{
26+
// need to cast NodeWrapper
27+
auto assImpNode = azrtti_cast<AZ::AssImpSDKWrapper::AssImpNodeWrapper*>(&sourceNode);
28+
auto assImpScene = azrtti_cast<AZ::AssImpSDKWrapper::AssImpSceneWrapper*>(&sourceScene);
29+
30+
if (!assImpNode)
31+
{
32+
// Handle error: parent is not of the expected type
33+
AZ_Error("SceneBuilder", false, "Incorrect node type. Cannot create NodeEncounteredContext");
34+
return nullptr;
35+
}
36+
if (!assImpScene)
37+
{
38+
AZ_Error("SceneBuilder", false, "Incorrect scene type. Cannot create NodeEncounteredContext");
39+
return nullptr;
40+
}
41+
return AZStd::make_shared<AssImpNodeEncounteredContext>(
42+
scene, currentGraphPosition, *assImpScene, sourceSceneSystem, nodeNameMap, *assImpNode);
43+
}
44+
45+
AZStd::shared_ptr<SceneDataPopulatedContextBase> AssImpImportContextProvider::CreateSceneDataPopulatedContext(
46+
NodeEncounteredContextBase& parent, AZStd::shared_ptr<DataTypes::IGraphObject> graphData, const AZStd::string& dataName)
47+
{
48+
// Downcast the parent to the AssImp-specific type to access AssImpImportContext members
49+
AssImpNodeEncounteredContext* assImpParent = azrtti_cast<AssImpNodeEncounteredContext*>(&parent);
50+
if (!assImpParent)
51+
{
52+
AZ_Error("SceneBuilder", false, "Incorrect type of parent. Cannot create SceneDataPopulatedContext");
53+
return nullptr;
54+
}
55+
56+
return AZStd::make_shared<AssImpSceneDataPopulatedContext>(*assImpParent, AZStd::move(graphData), dataName);
57+
}
58+
59+
AZStd::shared_ptr<SceneNodeAppendedContextBase> AssImpImportContextProvider::CreateSceneNodeAppendedContext(
60+
SceneDataPopulatedContextBase& parent, Containers::SceneGraph::NodeIndex newIndex)
61+
{
62+
// Downcast the parent to the AssImp-specific type
63+
AssImpSceneDataPopulatedContext* assImpParent = azrtti_cast<AssImpSceneDataPopulatedContext*>(&parent);
64+
if (!assImpParent)
65+
{
66+
AZ_Error("SceneBuilder", false, "Incorrect type of parent. Cannot create SceneNodeAppendedContext");
67+
return nullptr;
68+
}
69+
70+
return AZStd::make_shared<AssImpSceneNodeAppendedContext>(*assImpParent, newIndex);
71+
}
72+
73+
AZStd::shared_ptr<SceneAttributeDataPopulatedContextBase> AssImpImportContextProvider::CreateSceneAttributeDataPopulatedContext(
74+
SceneNodeAppendedContextBase& parent,
75+
AZStd::shared_ptr<DataTypes::IGraphObject> nodeData,
76+
const Containers::SceneGraph::NodeIndex attributeNodeIndex,
77+
const AZStd::string& dataName)
78+
{
79+
// Downcast the parent to the AssImp-specific type
80+
AssImpSceneNodeAppendedContext* assImpParent = azrtti_cast<AssImpSceneNodeAppendedContext*>(&parent);
81+
if (!assImpParent)
82+
{
83+
AZ_Error("SceneBuilder", false, "Incorrect type of parent. Cannot create SceneAttributeDataPopulatedContext");
84+
return nullptr;
85+
}
86+
return AZStd::make_shared<AssImpSceneAttributeDataPopulatedContext>(
87+
*assImpParent, AZStd::move(nodeData), attributeNodeIndex, dataName);
88+
}
89+
90+
AZStd::shared_ptr<SceneAttributeNodeAppendedContextBase> AssImpImportContextProvider::CreateSceneAttributeNodeAppendedContext(
91+
SceneAttributeDataPopulatedContextBase& parent, Containers::SceneGraph::NodeIndex newIndex)
92+
{
93+
// Downcast the parent to the AssImp-specific type
94+
AssImpSceneAttributeDataPopulatedContext* assImpParent = azrtti_cast<AssImpSceneAttributeDataPopulatedContext*>(&parent);
95+
if (!assImpParent)
96+
{
97+
AZ_Error("SceneBuilder", false, "Incorrect type of parent. Cannot create SceneAttributeNodeAppendedContext");
98+
return nullptr;
99+
}
100+
return AZStd::make_shared<AssImpSceneAttributeNodeAppendedContext>(*assImpParent, newIndex);
101+
}
102+
103+
AZStd::shared_ptr<SceneNodeAddedAttributesContextBase> AssImpImportContextProvider::CreateSceneNodeAddedAttributesContext(
104+
SceneNodeAppendedContextBase& parent)
105+
{
106+
// Downcast the parent to the AssImp-specific type
107+
AssImpSceneNodeAppendedContext* assImpParent = azrtti_cast<AssImpSceneNodeAppendedContext*>(&parent);
108+
if (!assImpParent)
109+
{
110+
AZ_Error("SceneBuilder", false, "Incorrect type of parent. Cannot create SceneNodeAddedAttributesContext");
111+
return nullptr;
112+
}
113+
return AZStd::make_shared<AssImpSceneNodeAddedAttributesContext>(*assImpParent);
114+
}
115+
116+
AZStd::shared_ptr<SceneNodeFinalizeContextBase> AssImpImportContextProvider::CreateSceneNodeFinalizeContext(
117+
SceneNodeAddedAttributesContextBase& parent)
118+
{
119+
// Downcast the parent to the AssImp-specific type
120+
AssImpSceneNodeAddedAttributesContext* assImpParent = azrtti_cast<AssImpSceneNodeAddedAttributesContext*>(&parent);
121+
if (!assImpParent)
122+
{
123+
AZ_Error("SceneBuilder", false, "Incorrect type of parent. Cannot create SceneNodeFinalizeContext");
124+
return nullptr;
125+
}
126+
return AZStd::make_shared<AssImpSceneNodeFinalizeContext>(*assImpParent);
127+
}
128+
129+
AZStd::shared_ptr<FinalizeSceneContextBase> AssImpImportContextProvider::CreateFinalizeSceneContext(
130+
Containers::Scene& scene,
131+
const SceneSystem& sourceSceneSystem,
132+
SDKScene::SceneWrapperBase& sourceScene,
133+
RenamedNodesMap& nodeNameMap)
134+
{
135+
AssImpSDKWrapper::AssImpSceneWrapper* assImpScene = azrtti_cast<AssImpSDKWrapper::AssImpSceneWrapper*>(&sourceScene);
136+
if (!assImpScene)
137+
{
138+
AZ_Error("SceneBuilder", false, "Incorrect scene type. Cannot create FinalizeSceneContext");
139+
return nullptr;
140+
}
141+
return AZStd::make_shared<AssImpFinalizeSceneContext>(scene, *assImpScene, sourceSceneSystem, nodeNameMap);
142+
}
143+
} // namespace SceneBuilder
144+
} // namespace SceneAPI
145+
} // namespace AZ

0 commit comments

Comments
 (0)