Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -0,0 +1,204 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <SceneAPI/SceneCore/Utilities/CoordinateSystemConverter.h>
#include <AzCore/Math/Matrix3x3.h>
namespace AZ::SceneAPI
{
// Default constructor, initializes so that it basically does no conversion.
CoordinateSystemConverter::CoordinateSystemConverter()
: m_sourceTransform(AZ::Transform::CreateIdentity())
, m_targetTransform(AZ::Transform::CreateIdentity())
, m_conversionTransform(AZ::Transform::CreateIdentity())
, m_conversionTransformInversed(AZ::Transform::CreateIdentity())
, m_needsConversion(false)
, m_sourceRightHanded(CheckIfIsRightHanded(m_sourceTransform))
, m_targetRightHanded(CheckIfIsRightHanded(m_targetTransform))
{
m_targetBasisIndices[0] = 0;
m_targetBasisIndices[1] = 1;
m_targetBasisIndices[2] = 2;
}
CoordinateSystemConverter::CoordinateSystemConverter(const AZ::Vector3 sourceBasisVectors[3], const AZ::Vector3 targetBasisVectors[3], const AZ::u32 targetBasisIndices[3])
{
const AZ::Matrix3x3 sourceMatrix3x3 = AZ::Matrix3x3::CreateFromColumns(sourceBasisVectors[0], sourceBasisVectors[1], sourceBasisVectors[2]);
m_sourceTransform = AZ::Transform::CreateFromMatrix3x3(sourceMatrix3x3);
AZ_Assert(m_sourceTransform.IsOrthogonal(), "Invalid source transformation, basis vectors have to be orthogonal.");
const AZ::Matrix3x3 targetMatrix3x3 = AZ::Matrix3x3::CreateFromColumns(targetBasisVectors[0], targetBasisVectors[1], targetBasisVectors[2]);
m_targetTransform = AZ::Transform::CreateFromMatrix3x3(targetMatrix3x3);
AZ_Assert(m_targetTransform.IsOrthogonal(), "Invalid target transformation, basis vectors have to be orthogonal.");
m_conversionTransform = m_targetTransform * m_sourceTransform.GetInverse();
m_conversionTransformInversed = m_conversionTransform.GetInverse();
m_targetBasisIndices[0] = targetBasisIndices[0];
m_targetBasisIndices[1] = targetBasisIndices[1];
m_targetBasisIndices[2] = targetBasisIndices[2];
m_needsConversion = (m_sourceTransform != m_targetTransform);
m_sourceRightHanded = CheckIfIsRightHanded(m_sourceTransform);
m_targetRightHanded = CheckIfIsRightHanded(m_targetTransform);
}
const CoordinateSystemConverter CoordinateSystemConverter::CreateFromBasisVectors(const AZ::Vector3 sourceBasisVectors[3], const AZ::Vector3 targetBasisVectors[3], const AZ::u32 targetBasisIndices[3])
{
return CoordinateSystemConverter(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
}
const CoordinateSystemConverter CoordinateSystemConverter::CreateFromTransforms(const AZ::Transform& sourceTransform, const AZ::Transform& targetTransform, const AZ::u32 targetBasisIndices[3])
{
AZ::Vector3 sourceBasisVectors[3];
sourceBasisVectors[0] = sourceTransform.GetBasisX();
sourceBasisVectors[1] = sourceTransform.GetBasisY();
sourceBasisVectors[2] = sourceTransform.GetBasisZ();
AZ::Vector3 targetBasisVectors[3];
targetBasisVectors[0] = targetTransform.GetBasisX();
targetBasisVectors[1] = targetTransform.GetBasisY();
targetBasisVectors[2] = targetTransform.GetBasisZ();
return CoordinateSystemConverter(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
}
bool CoordinateSystemConverter::CheckIfIsRightHanded(const AZ::Transform& transform) const
{
const AZ::Vector3 right = transform.GetBasisX();
const AZ::Vector3 up = transform.GetBasisY();
const AZ::Vector3 forward = transform.GetBasisZ();
return ((right.Cross(up)).Dot(forward) <= 0.0f);
}
//-------------------------------------------------------------------------
// Conversions
//-------------------------------------------------------------------------
AZ::Quaternion CoordinateSystemConverter::ConvertQuaternion(const AZ::Quaternion& input) const
{
if (!m_needsConversion)
{
return input;
}
const AZ::Vector3 vec = ConvertVector3( input.GetImaginary() );
float w = input.GetW();
if (m_sourceRightHanded != m_targetRightHanded)
{
w = -w;
}
return AZ::Quaternion(vec.GetX(), vec.GetY(), vec.GetZ(), w);
}
AZ::Vector3 CoordinateSystemConverter::ConvertVector3(const AZ::Vector3& input) const
{
if (!m_needsConversion)
{
return input;
}
return m_conversionTransform.TransformPoint(input);
}
AZ::Transform CoordinateSystemConverter::ConvertTransform(const AZ::Transform& input) const
{
if (!m_needsConversion)
{
return input;
}
return input * m_conversionTransform;
}
AZ::Matrix3x4 CoordinateSystemConverter::ConvertMatrix3x4(const AZ::Matrix3x4 & input) const
{
if (!m_needsConversion)
{
return input;
}
return input * AZ::Matrix3x4::CreateFromTransform(m_conversionTransform);
}
// Convert a scale value, which never flips some axis or so, just switches them.
// Think of two coordinate systems, where for example the Z axis is inverted in one of them, the scale will remain the same, in both systems.
// However, if we swap Y and Z, the scale Y and Z still have to be swapped.
AZ::Vector3 CoordinateSystemConverter::ConvertScale(const AZ::Vector3& input) const
{
if (!m_needsConversion)
{
return input;
}
return AZ::Vector3( input.GetElement(m_targetBasisIndices[0]),
input.GetElement(m_targetBasisIndices[1]),
input.GetElement(m_targetBasisIndices[2]) );
}
//-------------------------------------------------------------------------
// Inverse Conversions
//-------------------------------------------------------------------------
AZ::Quaternion CoordinateSystemConverter::InverseConvertQuaternion(const AZ::Quaternion& input) const
{
if (!m_needsConversion)
{
return input;
}
const AZ::Vector3 vec = InverseConvertVector3( input.GetImaginary() );
float w = input.GetW();
if (m_sourceRightHanded != m_targetRightHanded)
{
w = -w;
}
return AZ::Quaternion(vec.GetX(), vec.GetY(), vec.GetZ(), w);
}
AZ::Vector3 CoordinateSystemConverter::InverseConvertVector3(const AZ::Vector3& input) const
{
if (!m_needsConversion)
{
return input;
}
return m_conversionTransformInversed.TransformPoint(input);
}
AZ::Transform CoordinateSystemConverter::InverseConvertTransform(const AZ::Transform& input) const
{
if (!m_needsConversion)
{
return input;
}
return input * m_conversionTransformInversed;
}
AZ::Vector3 CoordinateSystemConverter::InverseConvertScale(const AZ::Vector3& input) const
{
return ConvertScale(input);
}
} // namespace AZ::SceneAPI
@@ -0,0 +1,69 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Quaternion.h>
#include <SceneAPI/SceneCore/SceneCoreConfiguration.h>
namespace AZ::SceneAPI
{
class SCENE_CORE_API CoordinateSystemConverter
{
public:
CoordinateSystemConverter();
static const CoordinateSystemConverter CreateFromBasisVectors(const AZ::Vector3 sourceBasisVectors[3], const AZ::Vector3 targetBasisVectors[3], const AZ::u32 targetBasisIndices[3]);
static const CoordinateSystemConverter CreateFromTransforms(const AZ::Transform& sourceTransform, const AZ::Transform& targetTransform, const AZ::u32 targetBasisIndices[3]);
// Inline get data.
bool IsConversionNeeded() const { return m_needsConversion; }
bool IsSourceRightHanded() const { return m_sourceRightHanded; }
bool IsTargetRightHanded() const { return m_targetRightHanded; }
const AZ::Transform GetSourceTransform() const { return m_sourceTransform; }
const AZ::Transform GetTargetTransform() const { return m_targetTransform; }
const AZ::Transform GetConversionTransform() const { return m_conversionTransform; }
const AZ::Transform GetInverseConversionTransform() const { return m_conversionTransformInversed; }
// Conversion methods.
AZ::Quaternion ConvertQuaternion(const AZ::Quaternion& input) const;
AZ::Vector3 ConvertVector3(const AZ::Vector3& input) const;
AZ::Vector3 ConvertScale(const AZ::Vector3& input) const;
AZ::Transform ConvertTransform(const AZ::Transform& input) const;
AZ::Matrix3x4 ConvertMatrix3x4(const AZ::Matrix3x4 & input) const;
// Inverse conversion methods.
AZ::Quaternion InverseConvertQuaternion(const AZ::Quaternion& input) const;
AZ::Vector3 InverseConvertVector3(const AZ::Vector3& input) const;
AZ::Vector3 InverseConvertScale(const AZ::Vector3& input) const;
AZ::Transform InverseConvertTransform(const AZ::Transform& input) const;
// Helper methods.
bool CheckIfIsRightHanded(const AZ::Transform& transform) const;
private:
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
AZ::Transform m_sourceTransform;
AZ::Transform m_targetTransform;
AZ::Transform m_conversionTransform;
AZ::Transform m_conversionTransformInversed;
AZ_POP_DISABLE_OVERRIDE_WARNING
AZ::u32 m_targetBasisIndices[3];
bool m_needsConversion;
bool m_sourceRightHanded;
bool m_targetRightHanded;
CoordinateSystemConverter(const AZ::Vector3 sourceBasisVectors[3], const AZ::Vector3 targetBasisVectors[3], const AZ::u32 targetBasisIndices[3]);
};
} // namespace AZ::SceneAPI
@@ -44,7 +44,18 @@ namespace AZ
return object && object->RTTI_IsTypeOf(DataTypes::IMeshData::TYPEINFO_Uuid());
}
AZStd::vector<AZStd::string> SceneGraphSelector::GenerateTargetNodes(const Containers::SceneGraph& graph, const DataTypes::ISceneNodeSelectionList& list, NodeFilterFunction nodeFilter)
Containers::SceneGraph::NodeIndex SceneGraphSelector::RemapToOptimizedMesh(const Containers::SceneGraph& graph, const Containers::SceneGraph::NodeIndex& index)
{
const auto& nodeName = graph.GetNodeName(index);
const AZStd::string optimizedName = AZStd::string(nodeName.GetPath(), nodeName.GetPathLength()) + "_optimized";
if (auto optimizedIndex = graph.Find(optimizedName); optimizedIndex.IsValid())
{
return optimizedIndex;
}
return index;
}
AZStd::vector<AZStd::string> SceneGraphSelector::GenerateTargetNodes(const Containers::SceneGraph& graph, const DataTypes::ISceneNodeSelectionList& list, NodeFilterFunction nodeFilter, NodeRemapFunction nodeRemap)
{
AZStd::vector<AZStd::string> targetNodes;
AZStd::set<AZStd::string> selectedNodesSet;
@@ -52,8 +63,8 @@ namespace AZ
CopySelectionToSet(selectedNodesSet, unselectedNodesSet, list);
CorrectRootNode(graph, selectedNodesSet, unselectedNodesSet);
auto nodeIterator = graph.ConvertToHierarchyIterator(graph.GetRoot());
auto view = Containers::Views::MakeSceneGraphDownwardsView<Containers::Views::BreadthFirst>(graph, nodeIterator, graph.GetContentStorage().cbegin(), true);
const auto nodeIterator = graph.ConvertToHierarchyIterator(graph.GetRoot());
const auto view = Containers::Views::MakeSceneGraphDownwardsView<Containers::Views::BreadthFirst>(graph, nodeIterator, graph.GetContentStorage().cbegin(), true);
if (view.begin() == view.end())
{
return targetNodes;
@@ -62,15 +73,24 @@ namespace AZ
{
Containers::SceneGraph::NodeIndex index = graph.ConvertToNodeIndex(it.GetHierarchyIterator());
AZStd::string currentNodeName = graph.GetNodeName(index).GetPath();
if (unselectedNodesSet.find(currentNodeName) != unselectedNodesSet.end())
if (unselectedNodesSet.contains(currentNodeName))
{
continue;
}
if (selectedNodesSet.find(currentNodeName) != selectedNodesSet.end())
if (selectedNodesSet.contains(currentNodeName))
{
if (nodeFilter(graph, index))
{
targetNodes.push_back(currentNodeName);
Containers::SceneGraph::NodeIndex remappedIndex = nodeRemap(graph, index);
if (remappedIndex == index)
{
targetNodes.emplace_back(AZStd::move(currentNodeName));
}
else
{
const Containers::SceneGraph::Name& nodeName = graph.GetNodeName(remappedIndex);
targetNodes.emplace_back(nodeName.GetPath(), nodeName.GetPathLength());
}
}
continue;
}
@@ -79,16 +99,25 @@ namespace AZ
if (parentIndex.IsValid())
{
AZStd::string parentNodeName = graph.GetNodeName(parentIndex).GetPath();
if (unselectedNodesSet.find(parentNodeName) != unselectedNodesSet.end())
if (unselectedNodesSet.contains(parentNodeName))
{
unselectedNodesSet.insert(currentNodeName);
}
else if (selectedNodesSet.find(parentNodeName) != selectedNodesSet.end())
else if (selectedNodesSet.contains(parentNodeName))
{
selectedNodesSet.insert(currentNodeName);
if (nodeFilter(graph, index))
{
targetNodes.push_back(currentNodeName);
Containers::SceneGraph::NodeIndex remappedIndex = nodeRemap(graph, index);
if (remappedIndex == index)
{
targetNodes.emplace_back(AZStd::move(currentNodeName));
}
else
{
const Containers::SceneGraph::Name& nodeName = graph.GetNodeName(remappedIndex);
targetNodes.emplace_back(nodeName.GetPath(), nodeName.GetPathLength());
}
}
}
else
@@ -159,12 +188,12 @@ namespace AZ
Containers::SceneGraph::NodeIndex index = graph.ConvertToNodeIndex(it.GetHierarchyIterator());
AZStd::string currentNodeName = it->first.GetPath();
// Check if item is already registered and if so add it to the appropriate list.
if (unselectedNodesSet.find(currentNodeName) != unselectedNodesSet.end())
if (unselectedNodesSet.contains(currentNodeName))
{
list.RemoveSelectedNode(AZStd::move(currentNodeName));
continue;
}
if (selectedNodesSet.find(currentNodeName) != selectedNodesSet.end())
if (selectedNodesSet.contains(currentNodeName))
{
list.AddSelectedNode(AZStd::move(currentNodeName));
continue;
@@ -176,7 +205,7 @@ namespace AZ
if (parentIndex.IsValid())
{
AZStd::string parentNodeName = graph.GetNodeName(parentIndex).GetPath();
if (unselectedNodesSet.find(parentNodeName) != unselectedNodesSet.end())
if (unselectedNodesSet.contains(parentNodeName))
{
unselectedNodesSet.insert(currentNodeName);
list.RemoveSelectedNode(AZStd::move(currentNodeName));
@@ -208,7 +237,7 @@ namespace AZ
AZStd::string currentNodeName = it->first.GetPath();
if (nodeFilter(graph, index))
{
if (targetNodes.find(currentNodeName) != targetNodes.end())
if (targetNodes.contains(currentNodeName))
{
list.AddSelectedNode(currentNodeName);
}
@@ -18,39 +18,38 @@
#include <AzCore/std/containers/unordered_set.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
namespace AZ
namespace AZ::SceneAPI::DataTypes { class ISceneNodeSelectionList; }
namespace AZ::SceneAPI::Utilities
{
namespace SceneAPI
// SceneGraphSelector provides utilities including converting selected and unselected node lists
// in the MeshGroup into the final target node list.
class SceneGraphSelector
{
namespace DataTypes
public:
using NodeFilterFunction = bool(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex& index);
using NodeRemapFunction = Containers::SceneGraph::NodeIndex(const Containers::SceneGraph& graph, const Containers::SceneGraph::NodeIndex& index);
SCENE_CORE_API static AZStd::vector<AZStd::string> GenerateTargetNodes(const Containers::SceneGraph& graph, const DataTypes::ISceneNodeSelectionList& list,
NodeFilterFunction nodeFilter, NodeRemapFunction nodeRemap = NoRemap);
SCENE_CORE_API static void SelectAll(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list);
SCENE_CORE_API static void UnselectAll(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list);
SCENE_CORE_API static void UpdateNodeSelection(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list);
SCENE_CORE_API static void UpdateTargetNodes(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list,
const AZStd::unordered_set<AZStd::string>& targetNodes, NodeFilterFunction nodeFilter);
SCENE_CORE_API static bool IsTreeViewType(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex& index);
SCENE_CORE_API static bool IsMesh(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex& index);
SCENE_CORE_API static bool IsMeshObject(const AZStd::shared_ptr<const DataTypes::IGraphObject>& object);
SCENE_CORE_API static Containers::SceneGraph::NodeIndex NoRemap(const Containers::SceneGraph& /*graph*/, const Containers::SceneGraph::NodeIndex& index)
{
class ISceneNodeSelectionList;
return index;
}
namespace Utilities
{
// SceneGraphSelector provides utilities including converting selected and unselected node lists
// in the MeshGroup into the final target node list.
class SceneGraphSelector
{
public:
using NodeFilterFunction = AZStd::function<bool(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex& index)>;
SCENE_CORE_API static Containers::SceneGraph::NodeIndex RemapToOptimizedMesh(const Containers::SceneGraph& graph, const Containers::SceneGraph::NodeIndex& index);
SCENE_CORE_API static AZStd::vector<AZStd::string> GenerateTargetNodes(const Containers::SceneGraph& graph, const DataTypes::ISceneNodeSelectionList& list,
NodeFilterFunction nodeFilter);
SCENE_CORE_API static void SelectAll(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list);
SCENE_CORE_API static void UnselectAll(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list);
SCENE_CORE_API static void UpdateNodeSelection(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list);
SCENE_CORE_API static void UpdateTargetNodes(const Containers::SceneGraph& graph, DataTypes::ISceneNodeSelectionList& list,
const AZStd::unordered_set<AZStd::string>& targetNodes, NodeFilterFunction nodeFilter);
SCENE_CORE_API static bool IsTreeViewType(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex& index);
SCENE_CORE_API static bool IsMesh(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex& index);
SCENE_CORE_API static bool IsMeshObject(const AZStd::shared_ptr<const DataTypes::IGraphObject>& object);
private:
static void CopySelectionToSet(AZStd::set<AZStd::string>& selected, AZStd::set<AZStd::string>& unselected, const DataTypes::ISceneNodeSelectionList& list);
static void CorrectRootNode(const Containers::SceneGraph& graph, AZStd::set<AZStd::string>& selected, AZStd::set<AZStd::string>& unselected);
};
}
}
}
private:
static void CopySelectionToSet(AZStd::set<AZStd::string>& selected, AZStd::set<AZStd::string>& unselected, const DataTypes::ISceneNodeSelectionList& list);
static void CorrectRootNode(const Containers::SceneGraph& graph, AZStd::set<AZStd::string>& selected, AZStd::set<AZStd::string>& unselected);
};
}