TSpace setting for MikkT tangent generation (#2386)

* Added TSpace method setting which is only visible for MikkT generation.
* Fixed a bug with generating tangents for blend shapes.
* Renamed tangent space into generation method.
* Some code cleaning

Signed-off-by: Benjamin Jillich <jillich@amazon.com>
This commit is contained in:
Benjamin Jillich
2021-07-27 00:15:26 -07:00
committed by GitHub
parent c9b3ed8bc7
commit a3712b5564
17 changed files with 385 additions and 371 deletions
@@ -10,110 +10,95 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace AZ
namespace AZ::SceneData::GraphData
{
namespace SceneData
void MeshVertexBitangentData::Reflect(ReflectContext* context)
{
namespace GraphData
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
void MeshVertexBitangentData::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<MeshVertexBitangentData>()->Version(2);
}
serializeContext->Class<MeshVertexBitangentData>()->Version(2);
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<MeshVertexBitangentData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetCount", &MeshVertexBitangentData::GetCount)
->Method("GetBitangent", &MeshVertexBitangentData::GetBitangent)
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
->Method("GetTangentSpace", &MeshVertexBitangentData::GetTangentSpace)
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
}
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<MeshVertexBitangentData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetCount", &MeshVertexBitangentData::GetCount)
->Method("GetBitangent", &MeshVertexBitangentData::GetBitangent)
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
->Method("GetGenerationMethod", &MeshVertexBitangentData::GetGenerationMethod)
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene>("FromSourceScene")
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::MikkT>("MikkT");
}
}
void MeshVertexBitangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
{
IMeshVertexBitangentData::CloneAttributesFrom(sourceObject);
if (const auto* typedSource = azrtti_cast<const MeshVertexBitangentData*>(sourceObject))
{
SetTangentSpace(typedSource->GetTangentSpace());
SetBitangentSetIndex(typedSource->GetBitangentSetIndex());
}
}
void MeshVertexBitangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
{
IMeshVertexBitangentData::CloneAttributesFrom(sourceObject);
if (const auto* typedSource = azrtti_cast<const MeshVertexBitangentData*>(sourceObject))
{
SetGenerationMethod(typedSource->GetGenerationMethod());
SetBitangentSetIndex(typedSource->GetBitangentSetIndex());
}
}
size_t MeshVertexBitangentData::GetCount() const
{
return m_bitangents.size();
}
size_t MeshVertexBitangentData::GetCount() const
{
return m_bitangents.size();
}
const AZ::Vector3& MeshVertexBitangentData::GetBitangent(size_t index) const
{
AZ_Assert(index < m_bitangents.size(), "Invalid index %i for mesh bitangents.", index);
return m_bitangents[index];
}
const AZ::Vector3& MeshVertexBitangentData::GetBitangent(size_t index) const
{
AZ_Assert(index < m_bitangents.size(), "Invalid index %i for mesh bitangents.", index);
return m_bitangents[index];
}
void MeshVertexBitangentData::ReserveContainerSpace(size_t numVerts)
{
m_bitangents.reserve(numVerts);
}
void MeshVertexBitangentData::Resize(size_t numVerts)
{
m_bitangents.resize(numVerts);
}
void MeshVertexBitangentData::ReserveContainerSpace(size_t numVerts)
{
m_bitangents.reserve(numVerts);
}
void MeshVertexBitangentData::AppendBitangent(const AZ::Vector3& bitangent)
{
m_bitangents.push_back(bitangent);
}
void MeshVertexBitangentData::SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent)
{
m_bitangents[vertexIndex] = bitangent;
}
void MeshVertexBitangentData::Resize(size_t numVerts)
{
m_bitangents.resize(numVerts);
}
void MeshVertexBitangentData::SetBitangentSetIndex(size_t setIndex)
{
m_setIndex = setIndex;
}
size_t MeshVertexBitangentData::GetBitangentSetIndex() const
{
return m_setIndex;
}
void MeshVertexBitangentData::AppendBitangent(const AZ::Vector3& bitangent)
{
m_bitangents.push_back(bitangent);
}
AZ::SceneAPI::DataTypes::TangentGenerationMethod MeshVertexBitangentData::GetGenerationMethod() const
{
return m_generationMethod;
}
void MeshVertexBitangentData::SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method)
{
m_generationMethod = method;
}
void MeshVertexBitangentData::SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent)
{
m_bitangents[vertexIndex] = bitangent;
}
void MeshVertexBitangentData::SetBitangentSetIndex(size_t setIndex)
{
m_setIndex = setIndex;
}
size_t MeshVertexBitangentData::GetBitangentSetIndex() const
{
return m_setIndex;
}
AZ::SceneAPI::DataTypes::TangentSpace MeshVertexBitangentData::GetTangentSpace() const
{
return m_tangentSpace;
}
void MeshVertexBitangentData::SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space)
{
m_tangentSpace = space;
}
void MeshVertexBitangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
{
output.Write("Bitangents", m_bitangents);
output.Write("TangentSpace", aznumeric_cast<int64_t>(m_tangentSpace));
}
} // GraphData
} // SceneData
} // AZ
void MeshVertexBitangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
{
output.Write("Bitangents", m_bitangents);
output.Write("GenerationMethod", aznumeric_cast<int64_t>(m_generationMethod));
}
} // AZ::SceneData::GraphData
@@ -10,51 +10,41 @@
#include <AzCore/Math/Vector3.h>
#include <AzCore/std/containers/vector.h>
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexBitangentData.h>
namespace AZ
namespace AZ::SceneData::GraphData
{
namespace SceneData
class SCENE_DATA_CLASS MeshVertexBitangentData
: public AZ::SceneAPI::DataTypes::IMeshVertexBitangentData
{
namespace GraphData
{
public:
AZ_RTTI(MeshVertexBitangentData, "{F56FB088-4C92-4453-AFE9-4E820F03FA90}", AZ::SceneAPI::DataTypes::IMeshVertexBitangentData);
class SCENE_DATA_CLASS MeshVertexBitangentData
: public AZ::SceneAPI::DataTypes::IMeshVertexBitangentData
{
public:
AZ_RTTI(MeshVertexBitangentData, "{F56FB088-4C92-4453-AFE9-4E820F03FA90}", AZ::SceneAPI::DataTypes::IMeshVertexBitangentData);
static void Reflect(ReflectContext* context);
static void Reflect(ReflectContext* context);
SCENE_DATA_API ~MeshVertexBitangentData() override = default;
SCENE_DATA_API ~MeshVertexBitangentData() override = default;
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
SCENE_DATA_API size_t GetCount() const override;
SCENE_DATA_API const AZ::Vector3& GetBitangent(size_t index) const override;
SCENE_DATA_API void SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent) override;
SCENE_DATA_API size_t GetCount() const override;
SCENE_DATA_API const AZ::Vector3& GetBitangent(size_t index) const override;
SCENE_DATA_API void SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent) override;
SCENE_DATA_API void SetBitangentSetIndex(size_t setIndex) override;
SCENE_DATA_API size_t GetBitangentSetIndex() const override;
SCENE_DATA_API void SetBitangentSetIndex(size_t setIndex) override;
SCENE_DATA_API size_t GetBitangentSetIndex() const override;
SCENE_DATA_API void Resize(size_t numVerts);
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
SCENE_DATA_API void AppendBitangent(const AZ::Vector3& bitangent);
SCENE_DATA_API void Resize(size_t numVerts);
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
SCENE_DATA_API void AppendBitangent(const AZ::Vector3& bitangent);
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentGenerationMethod GetGenerationMethod() const override;
SCENE_DATA_API void SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method) override;
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const override;
SCENE_DATA_API void SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space) override;
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
protected:
AZStd::vector<AZ::Vector3> m_bitangents;
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
size_t m_setIndex = 0;
};
} // GraphData
} // SceneData
} // AZ
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
protected:
AZStd::vector<AZ::Vector3> m_bitangents;
AZ::SceneAPI::DataTypes::TangentGenerationMethod m_generationMethod = AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene;
size_t m_setIndex = 0;
};
} // AZ::SceneData::GraphData
@@ -10,112 +10,96 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace AZ
namespace AZ::SceneData::GraphData
{
namespace SceneData
void MeshVertexTangentData::Reflect(ReflectContext* context)
{
namespace GraphData
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
void MeshVertexTangentData::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<MeshVertexTangentData>()->Version(2);
}
serializeContext->Class<MeshVertexTangentData>()->Version(2);
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<MeshVertexTangentData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetCount", &MeshVertexTangentData::GetCount)
->Method("GetTangent", &MeshVertexTangentData::GetTangent)
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
->Method("GetTangentSpace", &MeshVertexTangentData::GetTangentSpace)
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
}
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<MeshVertexTangentData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetCount", &MeshVertexTangentData::GetCount)
->Method("GetTangent", &MeshVertexTangentData::GetTangent)
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
->Method("GetGenerationMethod", &MeshVertexTangentData::GetGenerationMethod)
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene>("FromSourceScene")
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::MikkT>("MikkT");
}
}
void MeshVertexTangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
{
IMeshVertexTangentData::CloneAttributesFrom(sourceObject);
if (const auto* typedSource = azrtti_cast<const MeshVertexTangentData*>(sourceObject))
{
SetTangentSpace(typedSource->GetTangentSpace());
SetTangentSetIndex(typedSource->GetTangentSetIndex());
}
}
void MeshVertexTangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
{
IMeshVertexTangentData::CloneAttributesFrom(sourceObject);
if (const auto* typedSource = azrtti_cast<const MeshVertexTangentData*>(sourceObject))
{
SetGenerationMethod(typedSource->GetGenerationMethod());
SetTangentSetIndex(typedSource->GetTangentSetIndex());
}
}
size_t MeshVertexTangentData::GetCount() const
{
return m_tangents.size();
}
size_t MeshVertexTangentData::GetCount() const
{
return m_tangents.size();
}
const AZ::Vector4& MeshVertexTangentData::GetTangent(size_t index) const
{
AZ_Assert(index < m_tangents.size(), "Invalid index %i for mesh tangents.", index);
return m_tangents[index];
}
const AZ::Vector4& MeshVertexTangentData::GetTangent(size_t index) const
{
AZ_Assert(index < m_tangents.size(), "Invalid index %i for mesh tangents.", index);
return m_tangents[index];
}
void MeshVertexTangentData::ReserveContainerSpace(size_t numVerts)
{
m_tangents.reserve(numVerts);
}
void MeshVertexTangentData::Resize(size_t numVerts)
{
m_tangents.resize(numVerts);
}
void MeshVertexTangentData::ReserveContainerSpace(size_t numVerts)
{
m_tangents.reserve(numVerts);
}
void MeshVertexTangentData::AppendTangent(const AZ::Vector4& tangent)
{
m_tangents.push_back(tangent);
}
void MeshVertexTangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
{
output.Write("Tangents", m_tangents);
output.Write("GenerationMethod", aznumeric_cast<int64_t>(m_generationMethod));
output.Write("SetIndex", aznumeric_cast<uint64_t>(m_setIndex));
}
void MeshVertexTangentData::Resize(size_t numVerts)
{
m_tangents.resize(numVerts);
}
void MeshVertexTangentData::SetTangent(size_t vertexIndex, const AZ::Vector4& tangent)
{
m_tangents[vertexIndex] = tangent;
}
void MeshVertexTangentData::SetTangentSetIndex(size_t setIndex)
{
m_setIndex = setIndex;
}
void MeshVertexTangentData::AppendTangent(const AZ::Vector4& tangent)
{
m_tangents.push_back(tangent);
}
size_t MeshVertexTangentData::GetTangentSetIndex() const
{
return m_setIndex;
}
void MeshVertexTangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
{
output.Write("Tangents", m_tangents);
output.Write("TangentSpace", aznumeric_cast<int64_t>(m_tangentSpace));
output.Write("SetIndex", aznumeric_cast<uint64_t>(m_setIndex));
}
AZ::SceneAPI::DataTypes::TangentGenerationMethod MeshVertexTangentData::GetGenerationMethod() const
{
return m_generationMethod;
}
void MeshVertexTangentData::SetTangent(size_t vertexIndex, const AZ::Vector4& tangent)
{
m_tangents[vertexIndex] = tangent;
}
void MeshVertexTangentData::SetTangentSetIndex(size_t setIndex)
{
m_setIndex = setIndex;
}
size_t MeshVertexTangentData::GetTangentSetIndex() const
{
return m_setIndex;
}
AZ::SceneAPI::DataTypes::TangentSpace MeshVertexTangentData::GetTangentSpace() const
{
return m_tangentSpace;
}
void MeshVertexTangentData::SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space)
{
m_tangentSpace = space;
}
} // GraphData
} // SceneData
} // AZ
void MeshVertexTangentData::SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method)
{
m_generationMethod = method;
}
} // AZ::SceneData::GraphData
@@ -14,46 +14,39 @@
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexTangentData.h>
namespace AZ
namespace AZ::SceneData::GraphData
{
namespace SceneData
class SCENE_DATA_CLASS MeshVertexTangentData
: public AZ::SceneAPI::DataTypes::IMeshVertexTangentData
{
namespace GraphData
{
public:
AZ_RTTI(MeshVertexTangentData, "{C16F0F38-8F8F-45A2-A33B-F2758922A7C4}", AZ::SceneAPI::DataTypes::IMeshVertexTangentData);
class SCENE_DATA_CLASS MeshVertexTangentData
: public AZ::SceneAPI::DataTypes::IMeshVertexTangentData
{
public:
AZ_RTTI(MeshVertexTangentData, "{C16F0F38-8F8F-45A2-A33B-F2758922A7C4}", AZ::SceneAPI::DataTypes::IMeshVertexTangentData);
static void Reflect(ReflectContext* context);
static void Reflect(ReflectContext* context);
SCENE_DATA_API ~MeshVertexTangentData() override = default;
SCENE_DATA_API ~MeshVertexTangentData() override = default;
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
SCENE_DATA_API size_t GetCount() const override;
SCENE_DATA_API const AZ::Vector4& GetTangent(size_t index) const override;
SCENE_DATA_API void SetTangent(size_t vertexIndex, const AZ::Vector4& tangent) override;
SCENE_DATA_API size_t GetCount() const override;
SCENE_DATA_API const AZ::Vector4& GetTangent(size_t index) const override;
SCENE_DATA_API void SetTangent(size_t vertexIndex, const AZ::Vector4& tangent) override;
SCENE_DATA_API void SetTangentSetIndex(size_t setIndex) override;
SCENE_DATA_API size_t GetTangentSetIndex() const override;
SCENE_DATA_API void SetTangentSetIndex(size_t setIndex) override;
SCENE_DATA_API size_t GetTangentSetIndex() const override;
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentGenerationMethod GetGenerationMethod() const override;
SCENE_DATA_API void SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method) override;
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const override;
SCENE_DATA_API void SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space) override;
SCENE_DATA_API void Resize(size_t numVerts);
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
SCENE_DATA_API void AppendTangent(const AZ::Vector4& tangent);
SCENE_DATA_API void Resize(size_t numVerts);
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
SCENE_DATA_API void AppendTangent(const AZ::Vector4& tangent);
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
protected:
AZStd::vector<AZ::Vector4> m_tangents;
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
size_t m_setIndex = 0;
};
} // GraphData
} // SceneData
} // AZ
protected:
AZStd::vector<AZ::Vector4> m_tangents;
AZ::SceneAPI::DataTypes::TangentGenerationMethod m_generationMethod = AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene;
size_t m_setIndex = 0;
};
} // AZ::SceneData::GraphData
@@ -26,13 +26,22 @@ namespace AZ
{
TangentsRule::TangentsRule()
: DataTypes::IRule()
, m_tangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT)
{
}
AZ::SceneAPI::DataTypes::TangentSpace TangentsRule::GetTangentSpace() const
AZ::SceneAPI::DataTypes::TangentGenerationMethod TangentsRule::GetGenerationMethod() const
{
return m_tangentSpace;
return m_generationMethod;
}
AZ::SceneAPI::DataTypes::MikkTSpaceMethod TangentsRule::GetMikkTSpaceMethod() const
{
return m_tSpaceMethod;
}
AZ::Crc32 TangentsRule::GetSpaceMethodVisibility() const
{
return (m_generationMethod == AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT) ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
}
void TangentsRule::Reflect(AZ::ReflectContext* context)
@@ -43,20 +52,29 @@ namespace AZ
return;
}
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(3)
->Field("tangentSpace", &TangentsRule::m_tangentSpace);
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(4)
->Field("tangentSpace", &TangentsRule::m_generationMethod)
->Field("tSpaceMethod", &TangentsRule::m_tSpaceMethod);
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class<TangentsRule>("Tangents", "Specify how tangents are imported or generated.")
->ClassElement(Edit::ClassElements::EditorData, "")
->Attribute("AutoExpand", true)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tangentSpace, "Tangent space", "Specify the tangent space used for normal map baking. Choose 'From Fbx' to extract the tangents and bitangents directly from the Fbx file. When there is no tangents rule or the Fbx has no tangents stored inside it, the 'MikkT' option will be used with orthogonal tangents of unit length, so with the normalize option enabled, using the first UV set.")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene, "From Source Scene")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->Attribute("AutoExpand", true)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_generationMethod, "Generation Method", "Specify the tangent generation method. Choose 'From Source Scene' to extract the tangents and bitangents directly from the source scene file. When there is no tangents rule or the source scene has no tangents stored inside it, the 'MikkT' option will be used.")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene, "From Source Scene")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT, "MikkT")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tSpaceMethod, "TSpace Method",
"TSpace generates the tangents and bitangents with their true magnitudes which can be used for relief mapping effects. "
" It calculates the 'real' bitangent which may not be perpendicular to the tangent. "
"However, both, the tangent and bitangent are perpendicular to the vertex normal. "
"TSpaceBasic calculates unit vector tangents and bitangents at pixel/vertex level which are sufficient for basic normal mapping.")
->EnumAttribute(AZ::SceneAPI::DataTypes::MikkTSpaceMethod::TSpace, "TSpace")
->EnumAttribute(AZ::SceneAPI::DataTypes::MikkTSpaceMethod::TSpaceBasic, "TSpaceBasic")
->Attribute(AZ::Edit::Attributes::Visibility, &TangentsRule::GetSpaceMethodVisibility);
;
}
}
@@ -45,12 +45,17 @@ namespace AZ
SCENE_DATA_API TangentsRule();
SCENE_DATA_API ~TangentsRule() override = default;
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const;
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentGenerationMethod GetGenerationMethod() const;
SCENE_DATA_API AZ::SceneAPI::DataTypes::MikkTSpaceMethod GetMikkTSpaceMethod() const;
static void Reflect(ReflectContext* context);
protected:
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace; /**< Specifies how to handle tangents. Either generate them, or import them. */
AZ::SceneAPI::DataTypes::TangentGenerationMethod m_generationMethod = AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT; /**< Specifies how to handle tangents. Either generate them, or import them. */
// MikkT specific settings
AZ::Crc32 GetSpaceMethodVisibility() const;
AZ::SceneAPI::DataTypes::MikkTSpaceMethod m_tSpaceMethod = AZ::SceneAPI::DataTypes::MikkTSpaceMethod::TSpace;
};
} // SceneData
} // SceneAPI
@@ -84,7 +84,7 @@ namespace AZ
auto* bitangentData = AZStd::any_cast<AZ::SceneData::GraphData::MeshVertexBitangentData>(&data);
bitangentData->AppendBitangent(AZ::Vector3{0.12f, 0.34f, 0.56f});
bitangentData->AppendBitangent(AZ::Vector3{0.77f, 0.88f, 0.99f});
bitangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
bitangentData->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene);
bitangentData->SetBitangentSetIndex(1);
return true;
}
@@ -94,7 +94,7 @@ namespace AZ
tangentData->AppendTangent(AZ::Vector4{0.12f, 0.34f, 0.56f, 0.78f});
tangentData->AppendTangent(AZ::Vector4{0.18f, 0.28f, 0.19f, 0.29f});
tangentData->AppendTangent(AZ::Vector4{0.21f, 0.43f, 0.65f, 0.87f});
tangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT);
tangentData->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT);
tangentData->SetTangentSetIndex(2);
return true;
}
@@ -318,7 +318,7 @@ namespace AZ
ExpectExecute("TestExpectFloatEquals(bitangentData.y, 0.88)");
ExpectExecute("TestExpectFloatEquals(bitangentData.z, 0.99)");
ExpectExecute("TestExpectIntegerEquals(meshVertexBitangentData:GetBitangentSetIndex(), 1)");
ExpectExecute("TestExpectTrue(meshVertexBitangentData:GetTangentSpace(), MeshVertexBitangentData.FromSourceScene)");
ExpectExecute("TestExpectTrue(meshVertexBitangentData:GetGenerationMethod(), MeshVertexBitangentData.FromSourceScene)");
}
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_MeshVertexTangentData_AccessWorks)
@@ -337,7 +337,7 @@ namespace AZ
ExpectExecute("TestExpectFloatEquals(tangentData.z, 0.19)");
ExpectExecute("TestExpectFloatEquals(tangentData.w, 0.29)");
ExpectExecute("TestExpectIntegerEquals(meshVertexTangentData:GetTangentSetIndex(), 2)");
ExpectExecute("TestExpectTrue(meshVertexTangentData:GetTangentSpace(), MeshVertexTangentData.EMotionFX)");
ExpectExecute("TestExpectTrue(meshVertexTangentData:GetGenerationMethod(), MeshVertexTangentData.EMotionFX)");
}
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_AnimationData_AccessWorks)