Skip to content

Decouple AssImp from Scene Importer #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: stabilization/25050
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Code/Tools/SceneAPI/SDKWrapper/AssImpNodeWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

struct aiScene;

struct aiNode;

namespace AZ
{
namespace AssImpSDKWrapper
Expand Down
36 changes: 34 additions & 2 deletions Code/Tools/SceneAPI/SDKWrapper/AssImpSceneWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <assimp/postprocess.h>

#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
Expand Down Expand Up @@ -38,7 +39,7 @@ namespace AZ
}

#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
void signal_handler([[maybe_unused]] int signal)
void signal_handler([[maybe_unused]] int signal)
{
AZ_TracePrintf(
SceneAPI::Utilities::ErrorWindow,
Expand Down Expand Up @@ -184,6 +185,37 @@ namespace AZ
result.first = static_cast<AssImpSceneWrapper::AxisVector>(frontVectorRead);
return result;
}
}//namespace AssImpSDKWrapper

float AssImpSceneWrapper::GetUnitSizeInMeters() const
{
float unitSizeInMeters;
float originalUnitSizeInMeters;
/* Check if metadata has information about "UnitScaleFactor" or "OriginalUnitScaleFactor".
* This particular metadata is FBX format only. */
if (m_assImpScene->mMetaData->HasKey("UnitScaleFactor") || m_assImpScene->mMetaData->HasKey("OriginalUnitScaleFactor"))
{
// If either metadata piece is not available, the default of 1 will be used.
m_assImpScene->mMetaData->Get("UnitScaleFactor", unitSizeInMeters);
m_assImpScene->mMetaData->Get("OriginalUnitScaleFactor", originalUnitSizeInMeters);

/* Conversion factor for converting from centimeters to meters.
* This applies to an FBX format in which the default unit is a centimeter. */
unitSizeInMeters = unitSizeInMeters * .01f;
}
else
{
// Some file formats (like DAE) embed the scale in the root transformation, so extract that scale from here.
auto rootTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(m_assImpScene->mRootNode->mTransformation);
unitSizeInMeters = rootTransform.ExtractScale().GetMaxElement();
}
return unitSizeInMeters;
}

AZ::Aabb AssImpSceneWrapper::GetAABB() const
{
return AZ::Aabb::CreateFromMinMaxValues(
m_aabb.mMin.x, m_aabb.mMin.y, m_aabb.mMin.z, m_aabb.mMax.x, m_aabb.mMax.y, m_aabb.mMax.z);
}
} // namespace AssImpSDKWrapper

} // namespace AZ
17 changes: 5 additions & 12 deletions Code/Tools/SceneAPI/SDKWrapper/AssImpSceneWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,13 @@ namespace AZ
void Clear() override;
void CalculateAABBandVertices(const aiScene* scene, aiAABB& aabb, uint32_t& vertices);

enum class AxisVector
{
X = 0,
Y = 1,
Z = 2,
Unknown
};

AZStd::pair<AxisVector, int32_t> GetUpVectorAndSign() const;
AZStd::pair<AxisVector, int32_t> GetFrontVectorAndSign() const;
AZStd::pair<AxisVector, int32_t> GetUpVectorAndSign() const override;
AZStd::pair<AxisVector, int32_t> GetFrontVectorAndSign() const override;
float GetUnitSizeInMeters() const override;

AZStd::string GetSceneFileName() const { return m_sceneFileName; }
aiAABB GetAABB() const { return m_aabb; }
uint32_t GetVertices() const { return m_vertices; }
AZ::Aabb GetAABB() const override;
uint32_t GetVerticesCount() const override { return m_vertices; }
protected:
const aiScene* m_assImpScene = nullptr;
AZStd::unique_ptr<Assimp::Importer> m_importer;
Expand Down
14 changes: 0 additions & 14 deletions Code/Tools/SceneAPI/SDKWrapper/AssImpTypeConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,6 @@ namespace AZ
return transform;
}

SceneAPI::DataTypes::MatrixType AssImpTypeConverter::ToTransform(const AZ::Matrix4x4& matrix)
{
SceneAPI::DataTypes::MatrixType transform;
for (int row = 0; row < 3; ++row)
{
for (int column = 0; column < 4; ++column)
{
transform.SetElement(row, column, matrix.GetElement(row, column));
}
}

return transform;
}

SceneAPI::DataTypes::Color AssImpTypeConverter::ToColor(const aiColor4D& color)
{
return AZ::SceneAPI::DataTypes::Color(color.r, color.g, color.b, color.a);
Expand Down
1 change: 0 additions & 1 deletion Code/Tools/SceneAPI/SDKWrapper/AssImpTypeConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ namespace AZ
{
public:
static SceneAPI::DataTypes::MatrixType ToTransform(const aiMatrix4x4& matrix);
static SceneAPI::DataTypes::MatrixType ToTransform(const AZ::Matrix4x4& matrix);
static SceneAPI::DataTypes::Color ToColor(const aiColor4D& color);
static AZ::Vector3 ToVector3(const aiVector3D& vector3);
};
Expand Down
2 changes: 0 additions & 2 deletions Code/Tools/SceneAPI/SDKWrapper/MaterialWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#include <AzCore/std/string/string.h>
#include <AzCore/Math/Vector3.h>

struct aiMaterial;

namespace AZ
{
namespace SDKMaterial
Expand Down
2 changes: 0 additions & 2 deletions Code/Tools/SceneAPI/SDKWrapper/NodeWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>

struct aiNode;

namespace AZ
{
namespace SDKNode
Expand Down
43 changes: 43 additions & 0 deletions Code/Tools/SceneAPI/SDKWrapper/SceneWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Math/Aabb.h>
#include <SceneAPI/SDKWrapper/SceneWrapper.h>

namespace AZ
Expand Down Expand Up @@ -36,5 +37,47 @@ namespace AZ
void SceneWrapperBase::Clear()
{
}

AZStd::pair<SceneWrapperBase::AxisVector, int32_t> SceneWrapperBase::GetUpVectorAndSign() const
{
return {AxisVector::Z, 1};
}

AZStd::pair<SceneWrapperBase::AxisVector, int32_t> SceneWrapperBase::GetFrontVectorAndSign() const
{
return { AxisVector::X, 1};
}

float SceneWrapperBase::GetUnitSizeInMeters() const
{
return 1.0f;
}

AZ::Aabb SceneWrapperBase::GetAABB() const
{
return AZ::Aabb::CreateNull();
}

uint32_t SceneWrapperBase::GetVerticesCount() const
{
return 0u;
}


SceneAPI::DataTypes::MatrixType SceneTypeConverter::ToTransform(const AZ::Matrix4x4& matrix)
{
SceneAPI::DataTypes::MatrixType transform;
for (int row = 0; row < 3; ++row)
{
for (int column = 0; column < 4; ++column)
{
transform.SetElement(row, column, matrix.GetElement(row, column));
}
}

return transform;
}


} //namespace SDKScene
}// namespace AZ
28 changes: 24 additions & 4 deletions Code/Tools/SceneAPI/SDKWrapper/SceneWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string.h>
#include <AzCore/Math/Aabb.h>
#include <SceneAPI/SDKWrapper/NodeWrapper.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
#include <SceneAPI/SceneCore/Import/SceneImportSettings.h>

struct aiScene;

namespace AZ
{
namespace SDKScene
Expand All @@ -31,8 +31,28 @@ namespace AZ

virtual void Clear();

enum class AxisVector
{
X = 0,
Y = 1,
Z = 2,
Unknown
};

virtual AZStd::pair<AxisVector, int32_t> GetUpVectorAndSign() const;
virtual AZStd::pair<AxisVector, int32_t> GetFrontVectorAndSign() const;
virtual float GetUnitSizeInMeters() const;
virtual AZ::Aabb GetAABB() const;
virtual uint32_t GetVerticesCount() const;

static const char* s_defaultSceneName;
};

} //namespace Scene
} //namespace AZ
class SceneTypeConverter
{
public:
static SceneAPI::DataTypes::MatrixType ToTransform(const AZ::Matrix4x4& matrix);
};

} // namespace SDKScene
} // namespace AZ
8 changes: 8 additions & 0 deletions Code/Tools/SceneAPI/SceneBuilder/DllMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#include <SceneAPI/SceneBuilder/Importers/AssImpBoneImporter.h>
#include <SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.h>
#include <SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.h>
#include <SceneAPI/SceneBuilder/ImportContexts/AssImpImportContextProvider.h>
#include <SceneAPI/SceneBuilder/SceneBuilderSystemComponent.h>


namespace AZ
{
Expand All @@ -50,6 +53,9 @@ namespace AZ
g_componentDescriptors.push_back(SceneBuilder::SceneImporter::CreateDescriptor());
g_componentDescriptors.push_back(SceneImportRequestHandler::CreateDescriptor());

// ImportContextProviderRegistry
g_componentDescriptors.push_back(SceneBuilderSystemComponent::CreateDescriptor());

// Node and attribute importers
g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpColorStreamImporter::CreateDescriptor());
Expand Down Expand Up @@ -103,6 +109,8 @@ namespace AZ

extern "C" AZ_DLL_EXPORT void InitializeDynamicModule()
{
// Scott-Meyers singleton as no clear way how to add SystemComponent to module
AZ::SceneAPI::SceneBuilder::ImportContextRegistryManager::GetInstance();
}
extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context)
{
Expand Down
46 changes: 46 additions & 0 deletions Code/Tools/SceneAPI/SceneBuilder/ImportContextRegistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once

#include <AzCore/Interface/Interface.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>

namespace AZ
{
namespace SceneAPI
{
namespace SceneBuilder
{
struct ImportContextProvider;

// ImportContextRegistry realizes Abstract Factory Pattern.
// It provides a family of objects related to a particular Import Context.
// Those include ImportContext specializations for different stages of the Import pipeline
// as well as Scene and Node wrappers.
// To add a new library for importing scene assets:
// - specialize and implement the ImportContextProvider
// - register specialization with this interface
class ImportContextRegistry
{
public:
AZ_RTTI(ImportContextRegistry, "{5faaaa8a-2497-41d7-8b5c-5af4390af776}");
AZ_CLASS_ALLOCATOR(ImportContextRegistry, AZ::SystemAllocator, 0);

virtual ~ImportContextRegistry() = default;

virtual void RegisterContextProvider(ImportContextProvider* provider) = 0;
virtual void UnregisterContextProvider(ImportContextProvider* provider) = 0;
virtual ImportContextProvider* SelectImportProvider(AZStd::string_view fileExtension) const = 0;
};

using ImportContextRegistryInterface = AZ::Interface<ImportContextRegistry>;
} // namespace SceneBuilder
} // namespace SceneAPI
} // namespace AZ
80 changes: 80 additions & 0 deletions Code/Tools/SceneAPI/SceneBuilder/ImportContextRegistryManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/

#include "ImportContextRegistryManager.h"

namespace AZ
{
namespace SceneAPI
{
namespace SceneBuilder
{
ImportContextRegistryManager::ImportContextRegistryManager()
{
// register AssImp default provider
auto assimpContextProvider = aznew AssImpImportContextProvider();
m_importContextProviders.push_back(AZStd::unique_ptr<ImportContextProvider>(assimpContextProvider));
};

void ImportContextRegistryManager::RegisterContextProvider(ImportContextProvider* provider)
{
if (provider)
{
m_importContextProviders.push_back(AZStd::unique_ptr<ImportContextProvider>(provider));
}
}

void ImportContextRegistryManager::UnregisterContextProvider(ImportContextProvider* provider)
{
AZ_TracePrintf("SceneAPI", "Unregistered ImportContextProvider %s", provider->GetImporterName().data());
for (auto it = m_importContextProviders.begin(); it != m_importContextProviders.end(); ++it)
{
if (it->get() == provider)
{
m_importContextProviders.erase(it);
break; // Assuming only one instance can be registered at a time
}
}
}

ImportContextProvider* ImportContextRegistryManager::SelectImportProvider(AZStd::string_view fileExtension) const
{
AZ_TracePrintf(
"SceneAPI",
"Finding ImportContextProvider (registered %d) suitable for extension: %.*s",
m_importContextProviders.size(),
static_cast<int>(fileExtension.length()),
fileExtension.data());
// search in reverse order since the default AssImp Provider can handle all extenstions
for (auto it = m_importContextProviders.rbegin(); it != m_importContextProviders.rend(); ++it)
{
if (it->get()->CanHandleExtension(fileExtension))
{
return it->get();
}
else
{
AZ_TracePrintf(
"SceneAPI",
"Importer %s cannot handle %.*s",
it->get()->GetImporterName().data(),
static_cast<int>(fileExtension.length()),
fileExtension.data());
}
}
return nullptr; // No provider found
}
ImportContextRegistryManager& ImportContextRegistryManager::GetInstance()
{
static ImportContextRegistryManager instance;
return instance;
}

} // namespace SceneBuilder
} // namespace SceneAPI
} // namespace AZ
Loading