Skip to content

Commit 4d1d783

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 4d1d783

17 files changed

+718
-96
lines changed

Code/Tools/SceneAPI/SDKWrapper/AssImpSceneWrapper.cpp

+14-11
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
* SPDX-License-Identifier: Apache-2.0 OR MIT
66
*
77
*/
8-
#include <AssImpTypeConverter.h>
98
#include <AzCore/Debug/Trace.h>
109
#include <AzCore/Settings/SettingsRegistry.h>
1110
#include <AzToolsFramework/Debug/TraceContext.h>
1211
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
1312
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
13+
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
1414
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
1515
#include <assimp/postprocess.h>
1616

@@ -39,11 +39,12 @@ namespace AZ
3939
}
4040

4141
#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
42-
void signal_handler([[maybe_unused]] int signal)
42+
void signal_handler([[maybe_unused]] int signal)
4343
{
4444
AZ_TracePrintf(
4545
SceneAPI::Utilities::ErrorWindow,
46-
"Failed to import scene with Asset Importer library. An %s has occurred in the library, this scene file cannot be parsed by the library.",
46+
"Failed to import scene with Asset Importer library. An %s has occurred in the library, this scene file cannot be parsed "
47+
"by the library.",
4748
signal == SIGABRT ? "assert" : "unknown error");
4849
}
4950
#endif // AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
@@ -59,7 +60,7 @@ namespace AZ
5960
#ifdef _WRITE_ABORT_MSG
6061
_set_abort_behavior(0, _WRITE_ABORT_MSG);
6162
#endif // #ifdef _WRITE_ABORT_MSG
62-
// Instead, capture any calls to abort with a signal handler, and report them.
63+
// Instead, capture any calls to abort with a signal handler, and report them.
6364
auto previous_handler = std::signal(SIGABRT, signal_handler);
6465
#endif // AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
6566

@@ -72,12 +73,11 @@ namespace AZ
7273
// aiProcess_JoinIdenticalVertices is not enabled because O3DE has a mesh optimizer that also does this,
7374
// this flag is disabled to keep AssImp output similar to FBX SDK to reduce downstream bugs for the initial AssImp release.
7475
// There's currently a minimum of properties and flags set to maximize compatibility with the existing node graph.
75-
unsigned int importFlags =
76-
aiProcess_Triangulate // Triangulates all faces of all meshes
77-
| static_cast<unsigned long>(aiProcess_GenBoundingBoxes) // Generate bounding boxes
78-
| aiProcess_GenNormals // Generate normals for meshes
79-
| (importSettings.m_optimizeScene ? aiProcess_OptimizeGraph : 0) // Merge excess scene nodes together
80-
| (importSettings.m_optimizeMeshes ? aiProcess_OptimizeMeshes : 0) // Combines meshes in the scene together
76+
unsigned int importFlags = aiProcess_Triangulate // Triangulates all faces of all meshes
77+
| static_cast<unsigned long>(aiProcess_GenBoundingBoxes) // Generate bounding boxes
78+
| aiProcess_GenNormals // Generate normals for meshes
79+
| (importSettings.m_optimizeScene ? aiProcess_OptimizeGraph : 0) // Merge excess scene nodes together
80+
| (importSettings.m_optimizeMeshes ? aiProcess_OptimizeMeshes : 0) // Combines meshes in the scene together
8181
;
8282

8383
// aiProcess_LimitBoneWeights is not enabled because it will remove bones which are not associated with a mesh.
@@ -101,7 +101,10 @@ namespace AZ
101101

102102
if (!m_assImpScene)
103103
{
104-
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to import Asset Importer Scene. Error returned: %s", m_importer->GetErrorString());
104+
AZ_TracePrintf(
105+
SceneAPI::Utilities::ErrorWindow,
106+
"Failed to import Asset Importer Scene. Error returned: %s",
107+
m_importer->GetErrorString());
105108
return false;
106109
}
107110

Code/Tools/SceneAPI/SceneBuilder/DllMain.cpp

+16-7
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());
@@ -103,6 +110,8 @@ namespace AZ
103110

104111
extern "C" AZ_DLL_EXPORT void InitializeDynamicModule()
105112
{
113+
// Scott-Meyers singleton as no clear way how to add SystemComponent to module
114+
AZ::SceneAPI::SceneBuilder::ImportContextRegistryManager::GetInstance();
106115
}
107116
extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context)
108117
{
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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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+
ImportContextRegistryManager& ImportContextRegistryManager::GetInstance()
73+
{
74+
static ImportContextRegistryManager instance;
75+
return instance;
76+
}
77+
78+
} // namespace SceneBuilder
79+
} // namespace SceneAPI
80+
} // namespace AZ
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
static ImportContextRegistryManager& GetInstance();
39+
private:
40+
AZStd::vector<AZStd::unique_ptr<ImportContextProvider>> m_importContextProviders;
41+
};
42+
} // namespace SceneBuilder
43+
} // namespace SceneAPI
44+
} // namespace AZ

0 commit comments

Comments
 (0)