Fixed LodRuleBehavior using wrong loop index (#5915)

* Fixed LodRuleBehavior using wrong loop index

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Add  unit test for LOD auto-add crash

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix macro usage

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix include

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
This commit is contained in:
amzn-mike
2021-12-01 09:04:49 -06:00
committed by GitHub
parent b2c13b24ff
commit 2065225099
6 changed files with 100 additions and 20 deletions
@@ -185,7 +185,7 @@ namespace AZ
if (lodCount > 0)
{
rule->AddLod();
selection.CopyTo(rule->GetNodeSelectionList(index));
selection.CopyTo(rule->GetNodeSelectionList(lodLevel));
}
else
{
@@ -13,6 +13,7 @@
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
#include <SceneAPI/SceneCore/Events/GraphMetaInfoBus.h>
#include <SceneAPI/SceneCore/Events/ManifestMetaInfoBus.h>
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
namespace AZ
{
@@ -27,7 +28,7 @@ namespace AZ
{
class LodRule;
class LodRuleBehavior
class SCENE_DATA_CLASS LodRuleBehavior
: public SceneCore::BehaviorComponent
, public Events::ManifestMetaInfoBus::Handler
, public Events::AssetImportRequestBus::Handler
@@ -36,18 +37,19 @@ namespace AZ
public:
AZ_COMPONENT(LodRuleBehavior, "{D2E19864-9A4B-41FD-8ACC-DA6756728CB3}", SceneCore::BehaviorComponent);
~LodRuleBehavior() override = default;
SCENE_DATA_API ~LodRuleBehavior() override = default;
void Activate() override;
void Deactivate() override;
SCENE_DATA_API void Activate() override;
SCENE_DATA_API void Deactivate() override;
static void Reflect(ReflectContext* context);
void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override;
Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
SCENE_DATA_API void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override;
SCENE_DATA_API Events::ProcessingResult UpdateManifest(
Containers::Scene& scene, ManifestAction action,
RequestingApplication requester) override;
void GetVirtualTypeName(AZStd::string& name, Crc32 type) override;
void GetAllVirtualTypes(AZStd::set<Crc32>& types) override;
SCENE_DATA_API void GetVirtualTypeName(AZStd::string& name, Crc32 type) override;
SCENE_DATA_API void GetAllVirtualTypes(AZStd::set<Crc32>& types) override;
private:
size_t SelectLodMeshes(const Containers::Scene& scene, DataTypes::ISceneNodeSelectionList& selection, size_t lodLevel) const;
@@ -21,7 +21,6 @@ namespace AZ
{
const size_t LodRule::m_maxLods;
AZ_CLASS_ALLOCATOR_IMPL(LodRule, SystemAllocator, 0)
SceneNodeSelectionList& LodRule::GetNodeSelectionList(size_t index)
{
+10 -10
View File
@@ -25,26 +25,26 @@ namespace AZ
}
namespace SceneData
{
class LodRule
class SCENE_DATA_CLASS LodRule
: public DataTypes::ILodRule
{
public:
AZ_RTTI(LodRule, "{6E796AC8-1484-4909-860A-6D3F22A7346F}", DataTypes::ILodRule);
AZ_CLASS_ALLOCATOR_DECL
AZ_CLASS_ALLOCATOR(LodRule, AZ::SystemAllocator, 0)
~LodRule() override = default;
SCENE_DATA_API ~LodRule() override = default;
SceneNodeSelectionList& GetNodeSelectionList(size_t index);
SCENE_DATA_API SceneNodeSelectionList& GetNodeSelectionList(size_t index);
DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) override;
const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) const override;
size_t GetLodCount() const override;
SCENE_DATA_API DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) override;
SCENE_DATA_API const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) const override;
SCENE_DATA_API size_t GetLodCount() const override;
void AddLod();
SCENE_DATA_API void AddLod();
static void Reflect(ReflectContext* context);
//The engine supports 6 total lods. 1 for the base model then 5 more lods.
//The rule only captures lods past level 0 so this is set to 5.
//The engine supports 6 total lods. 1 for the base model then 5 more lods.
//The rule only captures lods past level 0 so this is set to 5.
static const size_t m_maxLods = 5;
protected:
@@ -11,5 +11,6 @@ set(FILES
Tests/GraphData/MeshDataTests.cpp
Tests/GraphData/MeshDataPrimitiveUtilsTests.cpp
Tests/GraphData/GraphDataBehaviorTests.cpp
Tests/GraphData/RulesTests.cpp
Tests/SceneManifest/SceneManifestRuleTests.cpp
)
@@ -0,0 +1,78 @@
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/Behaviors/LodRuleBehavior.h>
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
#include <SceneAPI/SceneData/Behaviors/Registry.h>
#include <SceneAPI/SceneData/Groups/MeshGroup.h>
#include <SceneAPI/SceneData/Rules/LodRule.h>
#include <SceneAPI/SceneData/Rules/TangentsRule.h>
namespace AZ
{
namespace SceneData
{
struct SoftNameMock
: SceneAPI::Events::GraphMetaInfoBus::Handler
{
SoftNameMock()
{
BusConnect();
}
~SoftNameMock() override
{
BusDisconnect();
}
void GetVirtualTypes(AZStd::set<Crc32>& types, const SceneAPI::Containers::Scene&, SceneAPI::Containers::SceneGraph::NodeIndex) override
{
// Indicate this node is a LOD1 type
types.emplace(AZ_CRC_CE("LODMesh1"));
}
};
TEST(LOD, LODRuleTest)
{
// Test that UpdateManifest doesn't crash when trying to auto-add new LOD levels
SoftNameMock softNameMock;
SceneAPI::SceneData::LodRuleBehavior lod;
SceneAPI::Containers::Scene scene("test");
auto lodRule = AZStd::shared_ptr<SceneAPI::SceneData::LodRule>(aznew SceneAPI::SceneData::LodRule());
scene.GetManifest().AddEntry(lodRule);
auto group = AZStd::shared_ptr<SceneAPI::SceneData::MeshGroup>(aznew SceneAPI::SceneData::MeshGroup());
// Add a bunch of other rules first
// This is necessary to replicate the bug condition where the index of the rule is used instead of the index of the LOD
for (int i = 0; i < 5; ++i)
{
auto tangentsRule = AZStd::shared_ptr<SceneAPI::SceneData::TangentsRule>(aznew SceneAPI::SceneData::TangentsRule());
group->GetRuleContainer().AddRule(tangentsRule);
}
group->GetRuleContainer().AddRule(lodRule);
scene.GetManifest().AddEntry(group);
auto meshData = AZStd::shared_ptr<GraphData::MeshData>(new GraphData::MeshData());
scene.GetGraph().AddChild(scene.GetGraph().GetRoot(), "test", meshData);
EXPECT_EQ(lodRule->GetLodCount(), 0);
// This should auto-add 1 LOD because of the "test" node we added above along with the SoftNameMock which will report it as an LOD1
lod.UpdateManifest(scene, SceneAPI::Events::AssetImportRequest::Update, SceneAPI::Events::AssetImportRequest::Generic);
EXPECT_EQ(lodRule->GetLodCount(), 1);
}
}
}