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
@@ -1,223 +0,0 @@
/*
* 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 <Cry_Geo.h> // Needed for CGFContent.h
#include <CGFContent.h>
#include <PropertyHelpers.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/ITouchBendingRule.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBoneData.h>
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphChildIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
#include <SceneAPI/SceneCore/Utilities/SceneGraphSelector.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <RC/ResourceCompilerScene/Common/ExportContextGlobal.h>
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
#include <RC/ResourceCompilerScene/Common/TouchBendingExporter.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/IMeshGroup.h> //Needed by CgfExportContexts.h
#include <RC/ResourceCompilerScene/Cgf/CgfExportContexts.h>
#include <RC/ResourceCompilerScene/Cgf/CgfUtils.h>
namespace AZ
{
namespace RC
{
namespace SceneEvents = AZ::SceneAPI::Events;
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
namespace SceneContainers = AZ::SceneAPI::Containers;
namespace SceneUtil = AZ::SceneAPI::Utilities;
namespace SceneViews = AZ::SceneAPI::Containers::Views;
namespace AzStringFunc = AzFramework::StringFunc;
TouchBendingExporter::TouchBendingExporter()
: AZ::SceneAPI::SceneCore::RCExportingComponent()
{
BindToCall(&TouchBendingExporter::ConfigureContainer);
BindToCall(&TouchBendingExporter::ProcessSkinnedMesh);
}
void TouchBendingExporter::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<TouchBendingExporter, AZ::SceneAPI::SceneCore::RCExportingComponent>()->Version(1);
}
}
SceneEvents::ProcessingResult TouchBendingExporter::ConfigureContainer(ContainerExportContext& context)
{
switch (context.m_phase)
{
case Phase::Filling:
{
AZStd::shared_ptr<const SceneDataTypes::ITouchBendingRule> touchBendingRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ITouchBendingRule>();
if (!touchBendingRule)
{
return SceneEvents::ProcessingResult::Ignored;
}
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
AZStd::vector<AZStd::string> noCollideTargetNodes = SceneUtil::SceneGraphSelector::GenerateTargetNodes(graph, touchBendingRule->GetSceneNodeSelectionList(), SceneUtil::SceneGraphSelector::IsMesh);
ProcessMeshType(context, context.m_container, noCollideTargetNodes, PHYS_GEOM_TYPE_NO_COLLIDE);
}
return SceneEvents::ProcessingResult::Success;
case Phase::Finalizing:
{
AZStd::shared_ptr<const SceneDataTypes::ITouchBendingRule> touchBendingRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ITouchBendingRule>();
if (!touchBendingRule)
{
return SceneEvents::ProcessingResult::Ignored;
}
//Let's make sure we have valid CSkinningInfo, otherwise,
//there's no point in adding the Bone Tree helper nodes.
CSkinningInfo* skinningInfo = context.m_container.GetSkinningInfo();
if (skinningInfo->m_arrBonesDesc.size() < 1)
{
return SceneEvents::ProcessingResult::Ignored;
}
AZStd::string rootBoneName = touchBendingRule->GetRootBoneName();
AddHelperBoneNodes(context, context.m_container, rootBoneName,
touchBendingRule->ShouldOverrideDamping(), touchBendingRule->GetOverrideDamping(),
touchBendingRule->ShouldOverrideStiffness(), touchBendingRule->GetOverrideStiffness(),
touchBendingRule->ShouldOverrideThickness(), touchBendingRule->GetOverrideThickness());
}
return SceneEvents::ProcessingResult::Success;
default:
return SceneEvents::ProcessingResult::Ignored;
}
}
SceneEvents::ProcessingResult TouchBendingExporter::ProcessSkinnedMesh(AZ::RC::MeshNodeExportContext& context)
{
if (context.m_physicalizeType != PHYS_GEOM_TYPE_NONE)
{
return SceneEvents::ProcessingResult::Ignored;
}
AZStd::shared_ptr<const SceneDataTypes::ITouchBendingRule> touchBendingRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ITouchBendingRule>();
if (!touchBendingRule)
{
return SceneEvents::ProcessingResult::Ignored;
}
AZStd::string rootBoneName = touchBendingRule->GetRootBoneName();
SceneEvents::ProcessingResult result = SceneEvents::ProcessingResult::Ignored;
switch (context.m_phase)
{
case Phase::Filling:
result = SceneEvents::Process<TouchBendableMeshNodeExportContext>(
context, rootBoneName, Phase::Filling);
break;
case Phase::Construction:
{
//Add the Bones to CSkinningInfo only if they have not been added already.
CSkinningInfo* skinningInfo = context.m_container.GetSkinningInfo();
if (skinningInfo->m_arrBonesDesc.size() == 0)
{
result = SceneEvents::Process<AddBonesToSkinningInfoContext>(
*skinningInfo, context.m_scene, rootBoneName);
}
}
break;
default:
break;
}
return result;
}
/*!
The format is based on Cry's PropertyHelpers::SetPropertyValue.
This version doesn't do any nullptr checking or white space trimming,
because those errors are guaranteed not to happen.
*/
static void AddPropertyValue(AZStd::string& inoutPropertiesString, const char* propertyName, float value, const char * propertySeparator)
{
char valueStr[16];
snprintf(valueStr, sizeof(valueStr), "%f", value);
AzStringFunc::Append(inoutPropertiesString, propertyName);
AzStringFunc::Append(inoutPropertiesString, '=');
AzStringFunc::Append(inoutPropertiesString, valueStr);
if (propertySeparator)
{
AzStringFunc::Append(inoutPropertiesString, propertySeparator);
}
}
bool TouchBendingExporter::AddHelperBoneNodes(AZ::RC::ContainerExportContext& context, CContentCGF& content, AZStd::string& rootBoneName,
[[maybe_unused]] bool shouldOverrideDamping, float damping,
[[maybe_unused]] bool shouldOverrideStiffness, float stiffness,
[[maybe_unused]] bool shouldOverrideThickness, float thickness)
{
AZ_TraceContext("AddHelperBoneNodes() rootBoneName:", rootBoneName);
if (rootBoneName.empty())
{
AZ_TracePrintf(TraceWindowName, "Root bone name cannot be empty.");
return false;
}
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
SceneContainers::SceneGraph::NodeIndex nodeIndex = graph.Find(rootBoneName);
if (!nodeIndex.IsValid())
{
AZ_TracePrintf(TraceWindowName, "Unable to find root bone in scene graph.");
return false;
}
auto contentStorage = graph.GetContentStorage();
auto nameStorage = graph.GetNameStorage();
auto pairView = SceneViews::MakePairView(contentStorage, nameStorage);
auto view = SceneViews::MakeSceneGraphDownwardsView<SceneViews::DepthFirst>(graph, nodeIndex, pairView.begin(), true);
int index = 0;
//Once SceneAPI supports Per Node Attributes, the string with properties
//should be built per Node. In the meantime, because all the properties are
//the same for all nodes, the string can be built once.
AZStd::string nodeProperties;
AddPropertyValue(nodeProperties, NODE_PROPERTY_DAMPING, damping, "\r\n");
AddPropertyValue(nodeProperties, NODE_PROPERTY_STIFFNESS, stiffness, "\r\n");
AddPropertyValue(nodeProperties, NODE_PROPERTY_THICKNESS, thickness, nullptr);
for (auto it = view.begin(); it != view.end(); ++it)
{
if (it->first && it->first->RTTI_IsTypeOf(SceneDataTypes::IBoneData::TYPEINFO_Uuid()))
{
//These very dummy nodes, are only used to define the name
//of the spines. It is not necessary to set transform matrices,
//nor it is relevant to set parent pointers, etc.
CNodeCGF* nodeCgf = new CNodeCGF();
SetNodeName(it->second.GetName(), *nodeCgf);
nodeCgf->type = CNodeCGF::NODE_HELPER;
nodeCgf->helperType = HP_POINT;
nodeCgf->properties = nodeProperties.c_str();
content.AddNode(nodeCgf);
}
else
{
// End of bone chain or interruption in the bone chain. In both cases stop looking into this part of hierarchy further.
it.IgnoreNodeDescendants();
}
}
return true;
}
} // namespace RC
} // namespace AZ
@@ -1,60 +0,0 @@
#pragma once
/*
* 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 <AzCore/std/string/string.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/unordered_map.h>
#include <SceneAPI/SceneCore/Components/RCExportingComponent.h>
struct CNodeCGF;
class CContentCGF;
namespace AZ
{
class ReflectContext;
namespace RC
{
struct CgfGroupExportContext;
struct ContainerExportContext;
struct MeshNodeExportContext;
class TouchBendingExporter
: public AZ::SceneAPI::SceneCore::RCExportingComponent
{
public:
AZ_COMPONENT(TouchBendingExporter, "{4C6694B3-F7A8-48D8-A10A-46D57F8CC75E}", AZ::SceneAPI::SceneCore::RCExportingComponent);
TouchBendingExporter();
~TouchBendingExporter() override = default;
static void Reflect(AZ::ReflectContext* context);
SceneAPI::Events::ProcessingResult ConfigureContainer(AZ::RC::ContainerExportContext& context);
SceneAPI::Events::ProcessingResult ProcessSkinnedMesh(AZ::RC::MeshNodeExportContext& context);
static constexpr const char * const TraceWindowName = "TouchBending";
protected:
/*!
StaticObjectCompiler, when building SFoliageInfoCGF, uses the "branch%d_%d" named bones to build the spines.
This methods adds the tree of CNodeCGF helper nodes from Bones with such names.
*/
bool AddHelperBoneNodes(AZ::RC::ContainerExportContext& context, CContentCGF& content, AZStd::string& rootBoneName,
bool shouldOverrideDamping, float damping,
bool shouldOverrideStiffness, float stiffness,
bool shouldOverrideThickness, float thickness);
}; //class TouchBendingCgfExporter
} // namespace RC
} //namespace AZ
@@ -1,199 +0,0 @@
/*
* 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 <Cry_Geo.h> // Needed for CGFContent.h
#include <CGFContent.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphChildIterator.h>
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/IOriginRule.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/IMeshGroup.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/ITransform.h>
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
#include <RC/ResourceCompilerScene/Common/WorldMatrixExporter.h>
namespace AZ
{
namespace RC
{
namespace SceneEvents = AZ::SceneAPI::Events;
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
namespace SceneContainers = AZ::SceneAPI::Containers;
namespace SceneViews = AZ::SceneAPI::Containers::Views;
WorldMatrixExporter::WorldMatrixExporter()
: m_cachedRootMatrix(MatrixType::CreateIdentity())
, m_cachedGroup(nullptr)
, m_cachedRootMatrixIsSet(false)
{
BindToCall(&WorldMatrixExporter::ProcessMeshGroup);
BindToCall(&WorldMatrixExporter::ProcessNode);
}
void WorldMatrixExporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<WorldMatrixExporter, SceneAPI::SceneCore::RCExportingComponent>()->Version(1);
}
}
SceneEvents::ProcessingResult WorldMatrixExporter::ProcessMeshGroup(ContainerExportContext& context)
{
if (context.m_phase != Phase::Construction)
{
return SceneEvents::ProcessingResult::Ignored;
}
m_cachedGroup = &context.m_group;
m_cachedRootMatrix = MatrixType::CreateIdentity();
m_cachedRootMatrixIsSet = false;
AZStd::shared_ptr<const SceneDataTypes::IOriginRule> rule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::IOriginRule>();
if (rule)
{
if (rule->GetTranslation() != Vector3(0.0f, 0.0f, 0.0f) || !rule->GetRotation().IsIdentity())
{
m_cachedRootMatrix = MatrixType::CreateFromQuaternionAndTranslation(rule->GetRotation(), rule->GetTranslation());
m_cachedRootMatrixIsSet = true;
}
if (rule->GetScale() != 1.0f)
{
float scale = rule->GetScale();
m_cachedRootMatrix.MultiplyByScale(Vector3(scale, scale, scale));
m_cachedRootMatrixIsSet = true;
}
if (!rule->GetOriginNodeName().empty() && !rule->UseRootAsOrigin())
{
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
SceneContainers::SceneGraph::NodeIndex index = graph.Find(rule->GetOriginNodeName());
if (index.IsValid())
{
MatrixType worldMatrix = MatrixType::CreateIdentity();
if (ConcatenateMatricesUpwards(worldMatrix, graph.ConvertToHierarchyIterator(index), graph))
{
worldMatrix.InvertFull();
m_cachedRootMatrix *= worldMatrix;
m_cachedRootMatrixIsSet = true;
}
}
}
return m_cachedRootMatrixIsSet ? SceneEvents::ProcessingResult::Success : SceneEvents::ProcessingResult::Ignored;
}
else
{
return SceneEvents::ProcessingResult::Ignored;
}
}
SceneEvents::ProcessingResult WorldMatrixExporter::ProcessNode(NodeExportContext& context)
{
if (context.m_phase != Phase::Filling)
{
return SceneEvents::ProcessingResult::Ignored;
}
MatrixType worldMatrix = MatrixType::CreateIdentity();
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
HierarchyStorageIterator nodeIterator = graph.ConvertToHierarchyIterator(context.m_nodeIndex);
bool translated = ConcatenateMatricesUpwards(worldMatrix, nodeIterator, graph);
AZ_Assert(m_cachedGroup == &context.m_group, "NodeExportContext doesn't belong to chain of previously called MeshGroupExportContext.");
if (m_cachedRootMatrixIsSet)
{
worldMatrix = m_cachedRootMatrix * worldMatrix;
translated = true;
}
//If we aren't merging nodes we need to put the transforms into the localTM
//due to how the CGFSaver works inside the ResourceCompilerPC code.
if (!context.m_container.GetExportInfo()->bMergeAllNodes)
{
SceneAPIMatrixTypeToMatrix34(context.m_node.localTM, worldMatrix);
}
else
{
SceneAPIMatrixTypeToMatrix34(context.m_node.worldTM, worldMatrix);
}
context.m_node.bIdentityMatrix = !translated;
return SceneEvents::ProcessingResult::Success;
}
bool WorldMatrixExporter::ConcatenateMatricesUpwards(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneContainers::SceneGraph& graph) const
{
bool translated = false;
auto view = SceneViews::MakeSceneGraphUpwardsView(graph, nodeIterator, graph.GetContentStorage().cbegin(), true);
for (auto it = view.begin(); it != view.end(); ++it)
{
if (!(*it))
{
continue;
}
const SceneDataTypes::ITransform* nodeTransform = azrtti_cast<const SceneDataTypes::ITransform*>(it->get());
if (nodeTransform)
{
transform = nodeTransform->GetMatrix() * transform;
translated = true;
}
else
{
bool endPointTransform = MultiplyEndPointTransforms(transform, it.GetHierarchyIterator(), graph);
translated = translated || endPointTransform;
}
}
return translated;
}
bool WorldMatrixExporter::MultiplyEndPointTransforms(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneContainers::SceneGraph& graph) const
{
// If the translation is not an end point it means it's its own group as opposed to being
// a component of the parent, so only list end point children.
auto view = SceneViews::MakeSceneGraphChildView<SceneViews::AcceptEndPointsOnly>(graph, nodeIterator,
graph.GetContentStorage().begin(), true);
auto result = AZStd::find_if(view.begin(), view.end(), SceneContainers::DerivedTypeFilter<SceneDataTypes::ITransform>());
if (result != view.end())
{
transform = azrtti_cast<const SceneDataTypes::ITransform*>(result->get())->GetMatrix() * transform;
return true;
}
else
{
return false;
}
}
void WorldMatrixExporter::SceneAPIMatrixTypeToMatrix34(Matrix34& out, const MatrixType& in) const
{
// Setting column instead of row because as of writing Matrix34 doesn't support adding
// full rows, as the translation has to be done separately.
for (int column = 0; column < 4; ++column)
{
Vector3 data = in.GetColumn(column);
out.SetColumn(column, Vec3(data.GetX(), data.GetY(), data.GetZ()));
}
}
} // namespace RC
} // namespace AZ
@@ -1,65 +0,0 @@
/*
* 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 <Cry_Matrix34.h>
#include <SceneAPI/SceneCore/Components/RCExportingComponent.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
namespace AZ
{
class Transform;
namespace SceneAPI
{
namespace DataTypes
{
class IOriginRule;
class IGroup;
}
}
namespace RC
{
struct ContainerExportContext;
struct NodeExportContext;
class WorldMatrixExporter
: public SceneAPI::SceneCore::RCExportingComponent
{
public:
AZ_COMPONENT(WorldMatrixExporter, "{65A0914C-5953-405F-819B-0E6EB96938F1}", SceneAPI::SceneCore::RCExportingComponent);
WorldMatrixExporter();
~WorldMatrixExporter() override = default;
static void Reflect(ReflectContext* context);
SceneAPI::Events::ProcessingResult ProcessMeshGroup(ContainerExportContext& context);
SceneAPI::Events::ProcessingResult ProcessNode(NodeExportContext& context);
protected:
using HierarchyStorageIterator = SceneAPI::Containers::SceneGraph::HierarchyStorageConstIterator;
using MatrixType = SceneAPI::DataTypes::MatrixType;
bool ConcatenateMatricesUpwards(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneAPI::Containers::SceneGraph& graph) const;
bool MultiplyEndPointTransforms(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneAPI::Containers::SceneGraph& graph) const;
void SceneAPIMatrixTypeToMatrix34(Matrix34& out, const MatrixType& in) const;
MatrixType m_cachedRootMatrix;
const SceneAPI::DataTypes::IGroup* m_cachedGroup;
bool m_cachedRootMatrixIsSet;
};
} // namespace RC
} // namespace AZ