{lyn9996} fixes for the default procedural prefab (#7354)
* {lyn9996} adding a default transform for procprefab
adding a default transform for procprefab when the DCC transform is
also a default transform. The import logic is not to create a
transform data node unless there is a delta.
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* cleaning up the code
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* adding unique optimized mesh entries using Mesh Group + Mesh Name
adding blank LOD rule to skip that logic for default proc prefab
unique mesh group names based on file name
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* updated a comment
bumped the scene builder version number
fixed up the mesh asset path for azmodel assets
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* update the proc prefab unit tests
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* fixing SceneProcessing MeshOptimizerComponentTests due to the name changes
in the mesh opt mesh group names now
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
This commit is contained in:
@@ -348,7 +348,7 @@ namespace UnitTest
|
||||
{
|
||||
AZ::SceneAPI::DataTypes::IMeshGroup* meshGroup = reinterpret_cast<AZ::SceneAPI::DataTypes::IMeshGroup*>(scene->GetManifest().GetValue(i).get());
|
||||
AZStd::string groupName = meshGroup->GetName();
|
||||
EXPECT_TRUE(groupName.starts_with("manifest_src_file_xml"));
|
||||
EXPECT_TRUE(groupName.starts_with("default_mock_"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,20 +30,21 @@
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemScriptingBus.h>
|
||||
#include <AzToolsFramework/Prefab/Procedural/ProceduralPrefabAsset.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
|
||||
#include <SceneAPI/SceneData/Groups/MeshGroup.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/FileUtilities.h>
|
||||
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
|
||||
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
|
||||
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/ITransform.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshData.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/SceneManifest.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Components/ExportingComponent.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Containers/SceneManifest.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshData.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/ITransform.h>
|
||||
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
|
||||
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
|
||||
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/FileUtilities.h>
|
||||
#include <SceneAPI/SceneData/Groups/MeshGroup.h>
|
||||
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/LodRule.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
@@ -98,6 +99,10 @@ namespace AZ::SceneAPI::Behaviors
|
||||
using MeshTransformPair = AZStd::pair<Containers::SceneGraph::NodeIndex, Containers::SceneGraph::NodeIndex>;
|
||||
using MeshTransformEntry = AZStd::pair<Containers::SceneGraph::NodeIndex, MeshTransformPair>;
|
||||
using MeshTransformMap = AZStd::unordered_map<Containers::SceneGraph::NodeIndex, MeshTransformPair>;
|
||||
using MeshIndexContainer = AZStd::unordered_set<Containers::SceneGraph::NodeIndex>;
|
||||
using ManifestUpdates = AZStd::vector<AZStd::shared_ptr<DataTypes::IManifestObject>>;
|
||||
using NodeEntityMap = AZStd::unordered_map<Containers::SceneGraph::NodeIndex, AZ::EntityId>;
|
||||
using EntityIdList = AZStd::vector<AZ::EntityId>;
|
||||
|
||||
MeshTransformMap CalculateMeshTransformMap(const Containers::Scene& scene)
|
||||
{
|
||||
@@ -108,47 +113,60 @@ namespace AZ::SceneAPI::Behaviors
|
||||
graph.GetContentStorage().cbegin(),
|
||||
true);
|
||||
|
||||
if (view.begin() == view.end())
|
||||
if (view.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
MeshIndexContainer meshIndexContainer;
|
||||
MeshTransformMap meshTransformMap;
|
||||
for (auto it = view.begin(); it != view.end(); ++it)
|
||||
{
|
||||
Containers::SceneGraph::NodeIndex currentIndex = graph.ConvertToNodeIndex(it.GetHierarchyIterator());
|
||||
AZStd::string currentNodeName = graph.GetNodeName(currentIndex).GetPath();
|
||||
auto currentContent = graph.GetNodeContent(currentIndex);
|
||||
const auto currentContent = graph.GetNodeContent(currentIndex);
|
||||
if (currentContent)
|
||||
{
|
||||
if (azrtti_istypeof<AZ::SceneAPI::DataTypes::ITransform>(currentContent.get()))
|
||||
{
|
||||
auto parentIndex = graph.GetNodeParent(currentIndex);
|
||||
const auto parentIndex = graph.GetNodeParent(currentIndex);
|
||||
if (parentIndex.IsValid() == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto parentContent = graph.GetNodeContent(parentIndex);
|
||||
const auto parentContent = graph.GetNodeContent(parentIndex);
|
||||
if (parentContent && azrtti_istypeof<AZ::SceneAPI::DataTypes::IMeshData>(parentContent.get()))
|
||||
{
|
||||
// map the node parent to the ITransform
|
||||
meshIndexContainer.erase(parentIndex);
|
||||
MeshTransformPair pair{ parentIndex, currentIndex };
|
||||
meshTransformMap.emplace(MeshTransformEntry{ graph.GetNodeParent(parentIndex), AZStd::move(pair) });
|
||||
}
|
||||
}
|
||||
else if (azrtti_istypeof<AZ::SceneAPI::DataTypes::IMeshData>(currentContent.get()))
|
||||
{
|
||||
meshIndexContainer.insert(currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// all mesh data nodes left in the meshIndexContainer do not have a matching TransformData node
|
||||
// since the nodes have an identity transform, so map the MeshData index with an Invalid mesh index to
|
||||
// indicate the transform should not be set to a default value
|
||||
for( const auto meshIndex : meshIndexContainer)
|
||||
{
|
||||
MeshTransformPair pair{ meshIndex, Containers::SceneGraph::NodeIndex{} };
|
||||
meshTransformMap.emplace(MeshTransformEntry{ graph.GetNodeParent(meshIndex), AZStd::move(pair) });
|
||||
}
|
||||
|
||||
return meshTransformMap;
|
||||
}
|
||||
|
||||
using ManifestUpdates = AZStd::vector<AZStd::shared_ptr<DataTypes::IManifestObject>>;
|
||||
using NodeEntityMap = AZStd::unordered_map<Containers::SceneGraph::NodeIndex, AZ::EntityId>;
|
||||
|
||||
NodeEntityMap CreateMeshGroups(
|
||||
ManifestUpdates& manifestUpdates,
|
||||
const MeshTransformMap& meshTransformMap,
|
||||
const Containers::Scene& scene,
|
||||
AZStd::string& relativeSourcePath)
|
||||
const AZStd::string& relativeSourcePath)
|
||||
{
|
||||
NodeEntityMap nodeEntityMap;
|
||||
const auto& graph = scene.GetGraph();
|
||||
@@ -158,15 +176,15 @@ namespace AZ::SceneAPI::Behaviors
|
||||
const auto thisNodeIndex = entry.first;
|
||||
const auto meshNodeIndex = entry.second.first;
|
||||
const auto meshNodeName = graph.GetNodeName(meshNodeIndex);
|
||||
AZStd::string meshNodePath{ meshNodeName.GetPath() };
|
||||
|
||||
AZStd::string meshNodeFullName;
|
||||
meshNodeFullName = relativeSourcePath;
|
||||
meshNodeFullName.append("_");
|
||||
meshNodeFullName.append(meshNodeName.GetName());
|
||||
AZStd::string meshNodePath{ meshNodeName.GetPath() };
|
||||
AZStd::string meshGroupName = "default_";
|
||||
meshGroupName += scene.GetName();
|
||||
meshGroupName += meshNodePath;
|
||||
AZ::StringFunc::Replace(meshGroupName, ".", "_");
|
||||
|
||||
auto meshGroup = AZStd::make_shared<AZ::SceneAPI::SceneData::MeshGroup>();
|
||||
meshGroup->SetName(meshNodeFullName);
|
||||
meshGroup->SetName(meshGroupName);
|
||||
meshGroup->GetSceneNodeSelectionList().AddSelectedNode(AZStd::move(meshNodePath));
|
||||
for (const auto& meshGoupNamePair : meshTransformMap)
|
||||
{
|
||||
@@ -190,6 +208,9 @@ namespace AZ::SceneAPI::Behaviors
|
||||
coordinateSystemRule->SetScale(1.0f);
|
||||
meshGroup->GetRuleContainer().AddRule(coordinateSystemRule);
|
||||
|
||||
// create an empty LOD rule in order to skip the LOD buffer creation
|
||||
meshGroup->GetRuleContainer().AddRule(AZStd::make_shared<AZ::SceneAPI::SceneData::LodRule>());
|
||||
|
||||
manifestUpdates.emplace_back(meshGroup);
|
||||
|
||||
// create an entity for each MeshGroup
|
||||
@@ -219,10 +240,15 @@ namespace AZ::SceneAPI::Behaviors
|
||||
}
|
||||
|
||||
// assign mesh asset id hint using JSON
|
||||
AZStd::string modelAssetPath;
|
||||
modelAssetPath = relativeSourcePath;
|
||||
AZ::StringFunc::Path::ReplaceFullName(modelAssetPath, meshGroupName.c_str());
|
||||
AZ::StringFunc::Replace(modelAssetPath, "\\", "/"); // asset paths use forward slashes
|
||||
|
||||
auto meshAssetJson = AZStd::string::format(
|
||||
R"JSON(
|
||||
{"Controller": {"Configuration": {"ModelAsset": { "assetHint": "%s.azmodel"}}}}
|
||||
)JSON", meshNodeFullName.c_str());
|
||||
)JSON", modelAssetPath.c_str());
|
||||
|
||||
bool result = false;
|
||||
AzToolsFramework::EntityUtilityBus::BroadcastResult(
|
||||
@@ -244,8 +270,6 @@ namespace AZ::SceneAPI::Behaviors
|
||||
return nodeEntityMap;
|
||||
}
|
||||
|
||||
using EntityIdList = AZStd::vector<AZ::EntityId>;
|
||||
|
||||
EntityIdList FixUpEntityParenting(
|
||||
const NodeEntityMap& nodeEntityMap,
|
||||
const Containers::SceneGraph& graph,
|
||||
@@ -303,7 +327,14 @@ namespace AZ::SceneAPI::Behaviors
|
||||
|
||||
// get node matrix data to set the entity's local transform
|
||||
const auto nodeTransform = azrtti_cast<const DataTypes::ITransform*>(graph.GetNodeContent(thisTransformIndex));
|
||||
entityTransform->SetLocalTM(AZ::Transform::CreateFromMatrix3x4(nodeTransform->GetMatrix()));
|
||||
if (nodeTransform)
|
||||
{
|
||||
entityTransform->SetLocalTM(AZ::Transform::CreateFromMatrix3x4(nodeTransform->GetMatrix()));
|
||||
}
|
||||
else
|
||||
{
|
||||
entityTransform->SetLocalTM(AZ::Transform::CreateUniformScale(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
return entities;
|
||||
|
||||
+4
-1
@@ -349,7 +349,10 @@ namespace AZ::SceneGenerationComponents
|
||||
}
|
||||
|
||||
const AZStd::string name =
|
||||
AZStd::string(graph.GetNodeName(nodeIndex).GetName(), graph.GetNodeName(nodeIndex).GetNameLength()).append(SceneAPI::Utilities::OptimizedMeshSuffix);
|
||||
AZStd::string(graph.GetNodeName(nodeIndex).GetName(), graph.GetNodeName(nodeIndex).GetNameLength())
|
||||
.append("_")
|
||||
.append(meshGroup.GetName())
|
||||
.append(SceneAPI::Utilities::OptimizedMeshSuffix);
|
||||
if (graph.Find(name).IsValid())
|
||||
{
|
||||
AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Optimized mesh already exists at '%s', there must be multiple mesh groups that have selected this mesh. Skipping the additional ones.", name.c_str());
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace SceneBuilder
|
||||
m_cachedFingerprint.append(element);
|
||||
}
|
||||
// A general catch all version fingerprint. Update this to force all FBX files to recompile.
|
||||
m_cachedFingerprint.append("Version 2");
|
||||
m_cachedFingerprint.append("Version 3");
|
||||
}
|
||||
|
||||
return m_cachedFingerprint.c_str();
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace SceneProcessing
|
||||
component.OptimizeMeshes(context);
|
||||
|
||||
AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex =
|
||||
graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix));
|
||||
graph.Find(AZStd::string("testMesh_").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix));
|
||||
ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh";
|
||||
|
||||
const auto& optimizedMesh =
|
||||
@@ -184,7 +184,7 @@ namespace SceneProcessing
|
||||
ASSERT_TRUE(optimizedMesh);
|
||||
|
||||
AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedSkinDataNodeIndex =
|
||||
graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix).append(".skinWeights"));
|
||||
graph.Find(AZStd::string("testMesh_").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix).append(".skinWeights"));
|
||||
ASSERT_TRUE(optimizedSkinDataNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the skin data";
|
||||
|
||||
const auto& optimizedSkinWeights =
|
||||
@@ -227,7 +227,7 @@ namespace SceneProcessing
|
||||
AZ::SceneAPI::Events::GenerateSimplificationEventContext context(scene, "pc");
|
||||
component.OptimizeMeshes(context);
|
||||
|
||||
AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix));
|
||||
AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh_").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix));
|
||||
ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh";
|
||||
|
||||
const auto& optimizedMesh = AZStd::rtti_pointer_cast<AZ::SceneAPI::DataTypes::IMeshData>(graph.GetNodeContent(optimizedNodeIndex));
|
||||
|
||||
Reference in New Issue
Block a user