Merge branch 'main' into carlitosan-beta-fixes
This commit is contained in:
@@ -60,6 +60,7 @@ namespace AzFramework
|
||||
virtual void DrawTrianglesIndexed(const AZStd::vector<AZ::Vector3>& vertices, const AZStd::vector<AZ::u32>& indices, const AZ::Color& color) { (void)vertices; (void)indices, (void)color; }
|
||||
virtual void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; }
|
||||
virtual void DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; }
|
||||
virtual void DrawWireOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; }
|
||||
virtual void DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; }
|
||||
virtual void DrawPoint(const AZ::Vector3& p, int nSize = 1) { (void)p; (void)nSize; }
|
||||
virtual void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) { (void)p1; (void)p2; }
|
||||
@@ -70,18 +71,15 @@ namespace AzFramework
|
||||
virtual void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) { (void)p1; (void)p2; (void)z; }
|
||||
virtual void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) { (void)p1; (void)p2; (void)z; (void)firstColor; (void)secondColor; }
|
||||
virtual void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) { (void)center; (void)radius; (void)z; }
|
||||
virtual void DrawTerrainCircle(const AZ::Vector3& worldPos, float radius, float height) { (void)worldPos; (void)radius; (void)height; }
|
||||
virtual void DrawTerrainCircle(const AZ::Vector3& center, float radius, float angle1, float angle2, float height) { (void)center; (void)radius; (void)angle1; (void)angle2; (void)height; }
|
||||
virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis = 2) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)referenceAxis; }
|
||||
virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)fixedAxis; }
|
||||
virtual void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)nUnchangedAxis; }
|
||||
virtual void DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)viewPos; (void)nUnchangedAxis; }
|
||||
virtual void DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height) { (void)pos; (void)dir; (void)radius; (void)height; }
|
||||
virtual void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) { (void)center; (void)axis; (void)radius; (void)height; }
|
||||
virtual void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) { (void)center; (void)axis; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) { (void)center; (void)axis; (void)radius; (void)heightStraightSection; }
|
||||
virtual void DrawTerrainRect(float x1, float y1, float x2, float y2, float height) { (void)x1; (void)y1; (void)x2; (void)y2; (void)height; }
|
||||
virtual void DrawTerrainLine(AZ::Vector3 worldPos1, AZ::Vector3 worldPos2) { (void)worldPos1; (void)worldPos2; }
|
||||
virtual void DrawWireSphere(const AZ::Vector3& pos, float radius) { (void)pos; (void)radius; }
|
||||
virtual void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) { (void)pos; (void)radius; }
|
||||
virtual void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) { (void)pos; (void)dir; (void)radius; }
|
||||
@@ -91,11 +89,8 @@ namespace AzFramework
|
||||
virtual void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) { (void)pos; (void)size; (void)text; (void)bCenter; (void)srcOffsetX; (void)srcOffsetY; }
|
||||
virtual void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) { (void)x; (void)y; (void)size; (void)text; (void)bCenter; }
|
||||
virtual void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) { (void)pos; (void)text; (void)textScale; (void)TextColor; (void)TextBackColor; }
|
||||
virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)texture; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; }
|
||||
virtual void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)textureId; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; }
|
||||
virtual void SetLineWidth(float width) { (void)width; }
|
||||
virtual bool IsVisible(const AZ::Aabb& bounds) { (void)bounds; return false; }
|
||||
virtual int SetFillMode(int nFillMode) { (void)nFillMode; return 0; }
|
||||
virtual float GetLineWidth() { return 0.0f; }
|
||||
virtual float GetAspectRatio() { return 0.0f; }
|
||||
virtual void DepthTestOff() {}
|
||||
|
||||
@@ -123,8 +123,9 @@ namespace AzFramework
|
||||
OctreeNode* insertCheck = this;
|
||||
while (insertCheck != nullptr)
|
||||
{
|
||||
if (AZ::ShapeIntersection::Contains(insertCheck->m_bounds, boundingVolume))
|
||||
if (AZ::ShapeIntersection::Contains(insertCheck->m_bounds, boundingVolume) || !insertCheck->m_parent)
|
||||
{
|
||||
// Insert here if the entry is fully contained or if we've reached the root node
|
||||
return insertCheck->Insert(octreeScene, entry);
|
||||
}
|
||||
insertCheck = insertCheck->m_parent;
|
||||
|
||||
+12
-1
@@ -81,9 +81,20 @@ namespace AzToolsFramework
|
||||
|
||||
m_ui->m_assetBrowserTreeViewWidget->SetName("AssetBrowserTreeView_" + name);
|
||||
|
||||
bool selectedAsset = false;
|
||||
|
||||
for (auto& assetId : selection.GetSelectedAssetIds())
|
||||
{
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId);
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
selectedAsset = true;
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedAsset)
|
||||
{
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory());
|
||||
}
|
||||
|
||||
setWindowTitle(tr("Pick %1").arg(m_selection.GetTitle()));
|
||||
|
||||
@@ -93,6 +93,16 @@ namespace AzToolsFramework
|
||||
m_selectedAssetIds.push_back(selectedAssetId);
|
||||
}
|
||||
|
||||
void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory)
|
||||
{
|
||||
m_defaultDirectory = defaultDirectory;
|
||||
}
|
||||
|
||||
AZStd::string_view AssetSelectionModel::GetDefaultDirectory() const
|
||||
{
|
||||
return m_defaultDirectory;
|
||||
}
|
||||
|
||||
AZStd::vector<const AssetBrowserEntry*>& AssetSelectionModel::GetResults()
|
||||
{
|
||||
return m_results;
|
||||
|
||||
@@ -47,6 +47,9 @@ namespace AzToolsFramework
|
||||
const AZStd::vector<AZ::Data::AssetId>& GetSelectedAssetIds() const;
|
||||
void SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds);
|
||||
void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId);
|
||||
|
||||
void SetDefaultDirectory(AZStd::string_view defaultDirectory);
|
||||
AZStd::string_view GetDefaultDirectory() const;
|
||||
|
||||
AZStd::vector<const AssetBrowserEntry*>& GetResults();
|
||||
const AssetBrowserEntry* GetResult();
|
||||
@@ -72,6 +75,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::vector<AZ::Data::AssetId> m_selectedAssetIds;
|
||||
AZStd::vector<const AssetBrowserEntry*> m_results;
|
||||
AZStd::string m_defaultDirectory;
|
||||
|
||||
QString m_title;
|
||||
};
|
||||
|
||||
+45
-18
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
@@ -270,7 +271,20 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entries, const uint32_t entryPathIndex)
|
||||
void AssetBrowserTreeView::SelectFolder(AZStd::string_view folderPath)
|
||||
{
|
||||
if (folderPath.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::vector<AZStd::string> entries;
|
||||
AZ::StringFunc::Tokenize(folderPath, entries, "/");
|
||||
|
||||
SelectEntry(QModelIndex(), entries, 0, true);
|
||||
}
|
||||
|
||||
bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entries, const uint32_t entryPathIndex, bool useDisplayName)
|
||||
{
|
||||
if (entries.empty())
|
||||
{
|
||||
@@ -285,30 +299,43 @@ namespace AzToolsFramework
|
||||
auto rowIdx = model()->index(idx, 0, idxParent);
|
||||
auto rowEntry = GetEntryFromIndex<AssetBrowserEntry>(rowIdx);
|
||||
|
||||
// Check if this entry name matches the query
|
||||
if (rowEntry && AzFramework::StringFunc::Equal(entry.c_str(), rowEntry->GetName().c_str(), true))
|
||||
if (rowEntry)
|
||||
{
|
||||
// Final entry found - set it as the selected element
|
||||
if (entryPathIndex == entries.size() - 1)
|
||||
{
|
||||
selectionModel()->clear();
|
||||
selectionModel()->select(rowIdx, QItemSelectionModel::Select);
|
||||
setCurrentIndex(rowIdx);
|
||||
return true;
|
||||
}
|
||||
// Check if this entry name matches the query
|
||||
AZStd::string_view compareName = useDisplayName ? (const char*)(rowEntry->GetDisplayName().toUtf8()) : rowEntry->GetName().c_str();
|
||||
|
||||
// If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out)
|
||||
if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
|
||||
if (AzFramework::StringFunc::Equal(entry.c_str(), compareName, true))
|
||||
{
|
||||
// Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset Browser (otherwise, early out)
|
||||
if (SelectEntry(rowIdx, entries, entryPathIndex + 1))
|
||||
// Final entry found - set it as the selected element
|
||||
if (entryPathIndex == entries.size() - 1)
|
||||
{
|
||||
expand(rowIdx);
|
||||
if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
|
||||
{
|
||||
// Expand the item itself if it is a folder
|
||||
expand(rowIdx);
|
||||
}
|
||||
|
||||
selectionModel()->clear();
|
||||
selectionModel()->select(rowIdx, QItemSelectionModel::Select);
|
||||
setCurrentIndex(rowIdx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out)
|
||||
if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
|
||||
{
|
||||
// Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset
|
||||
// Browser (otherwise, early out)
|
||||
if (SelectEntry(rowIdx, entries, entryPathIndex + 1, useDisplayName))
|
||||
{
|
||||
expand(rowIdx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -60,6 +60,8 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::vector<AssetBrowserEntry*> GetSelectedAssets() const;
|
||||
|
||||
void SelectFolder(AZStd::string_view folderPath);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AssetBrowserViewRequestBus
|
||||
void SelectProduct(AZ::Data::AssetId assetID) override;
|
||||
@@ -67,6 +69,7 @@ namespace AzToolsFramework
|
||||
void ClearFilter() override;
|
||||
|
||||
void Update() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -105,7 +108,7 @@ namespace AzToolsFramework
|
||||
QString m_name;
|
||||
|
||||
bool SelectProduct(const QModelIndex& idxParent, AZ::Data::AssetId assetID);
|
||||
bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entryPathTokens, const uint32_t entryPathIndex = 0);
|
||||
bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entryPathTokens, const uint32_t entryPathIndex = 0, bool useDisplayName = false);
|
||||
|
||||
//! Grab one entry from the source thumbnail list and update it
|
||||
void UpdateSCThumbnails();
|
||||
|
||||
@@ -447,17 +447,14 @@ namespace AzToolsFramework
|
||||
m_radius * viewScale);
|
||||
|
||||
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
|
||||
|
||||
// show wireframe if the axis has been corrected/flipped
|
||||
// note: please see IRenderAuxGeom.h for the definition of e_FillModeWireframe and e_FillModeSolid.
|
||||
// it is not possible to include IRenderAuxGeom from here and we also don't want to introduce that dependency.
|
||||
// these legacy enums should be wrapped so set SetFillMode can be used in a type safe way, until then,
|
||||
// use the values directly until the API has been updated.
|
||||
const AZ::u32 prevFillMode = debugDisplay.SetFillMode(
|
||||
m_shouldCorrect ? /*e_FillModeWireframe =*/ 0x1 << 26 : /*e_FillModeSolid =*/ 0);
|
||||
|
||||
debugDisplay.DrawCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height, false);
|
||||
debugDisplay.SetFillMode(prevFillMode);
|
||||
if (m_shouldCorrect)
|
||||
{
|
||||
debugDisplay.DrawWireCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
debugDisplay.DrawSolidCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height, false);
|
||||
}
|
||||
|
||||
RefreshBoundInternal(managerId, manipulatorId, coneBound);
|
||||
}
|
||||
|
||||
+1
-2
@@ -140,8 +140,7 @@ namespace AzToolsFramework
|
||||
ProductAssetBrowserEntry* productEntry = static_cast<ProductAssetBrowserEntry*>(childEntry);
|
||||
AZStd::string assetName;
|
||||
AzFramework::StringFunc::Path::GetFileName(productEntry->GetFullPath().c_str(), assetName);
|
||||
m_assets.push_back({
|
||||
assetName, productEntry->GetFullPath(), productEntry->GetAssetId()
|
||||
m_assets.push_back({ productEntry->GetName(), productEntry->GetFullPath(), productEntry->GetAssetId()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+18
@@ -769,6 +769,14 @@ namespace AzToolsFramework
|
||||
// Request the AssetBrowser Dialog and set a type filter
|
||||
AssetSelectionModel selection = GetAssetSelectionModel();
|
||||
selection.SetSelectedAssetId(m_selectedAssetID);
|
||||
|
||||
AZStd::string defaultDirectory;
|
||||
if (m_defaultDirectoryCallback)
|
||||
{
|
||||
m_defaultDirectoryCallback->Invoke(m_editNotifyTarget, defaultDirectory);
|
||||
selection.SetDefaultDirectory(defaultDirectory);
|
||||
}
|
||||
|
||||
AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, parentWidget());
|
||||
if (selection.IsValid())
|
||||
{
|
||||
@@ -1080,6 +1088,11 @@ namespace AzToolsFramework
|
||||
m_editNotifyCallback = editNotifyCallback;
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback)
|
||||
{
|
||||
m_defaultDirectoryCallback = callback;
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback)
|
||||
{
|
||||
m_clearNotifyCallback = clearNotifyCallback;
|
||||
@@ -1214,6 +1227,11 @@ namespace AzToolsFramework
|
||||
GUI->SetTitle(title.c_str());
|
||||
}
|
||||
}
|
||||
else if (attrib == AZ_CRC_CE("DefaultStartingDirectoryCallback"))
|
||||
{
|
||||
// This is assumed to be an Asset Browser path to a specific folder to be used as a default by the asset picker if provided
|
||||
GUI->SetDefaultDirectoryCallback(azdynamic_cast<PropertyAssetCtrl::DefaultDirectoryCallbackType*>(attrValue->GetAttribute()));
|
||||
}
|
||||
else if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1))
|
||||
{
|
||||
PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute());
|
||||
|
||||
+3
@@ -68,6 +68,7 @@ namespace AzToolsFramework
|
||||
// This is meant to be used with the "EditCallback" Attribute
|
||||
using EditCallbackType = AZ::Edit::AttributeFunction<void(const AZ::Data::AssetId&, const AZ::Data::AssetType&)>;
|
||||
using ClearCallbackType = AZ::Edit::AttributeFunction<void()>;
|
||||
using DefaultDirectoryCallbackType = AZ::Edit::AttributeFunction<void(AZStd::string&)>;
|
||||
|
||||
PropertyAssetCtrl(QWidget *pParent = NULL, QString optionalValidDragDropExtensions = QString());
|
||||
virtual ~PropertyAssetCtrl();
|
||||
@@ -119,6 +120,7 @@ namespace AzToolsFramework
|
||||
EditCallbackType* m_editNotifyCallback = nullptr;
|
||||
ClearCallbackType* m_clearNotifyCallback = nullptr;
|
||||
QString m_optionalValidDragDropExtensions;
|
||||
DefaultDirectoryCallbackType* m_defaultDirectoryCallback = nullptr;
|
||||
|
||||
//! The number of characters after which the autocompleter dropdown will be shown.
|
||||
// Prevents showing too many options.
|
||||
@@ -196,6 +198,7 @@ namespace AzToolsFramework
|
||||
void SetEditNotifyTarget(void* editNotifyTarget);
|
||||
void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute
|
||||
void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute
|
||||
void SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback); // This is meant to be used with the "DefaultStartingDirectoryCallback" Attribute
|
||||
void SetEditButtonEnabled(bool enabled);
|
||||
void SetEditButtonVisible(bool visible);
|
||||
void SetEditButtonIcon(const QIcon& icon);
|
||||
|
||||
+3
-3
@@ -233,9 +233,9 @@ namespace AzToolsFramework
|
||||
}();
|
||||
|
||||
debugDisplay.SetColor(iconHighlight);
|
||||
debugDisplay.DrawTextureLabel(
|
||||
iconTextureId, entityPosition, iconSize, iconSize,
|
||||
/*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008);
|
||||
// debugDisplay.DrawTextureLabel(
|
||||
// iconTextureId, entityPosition, iconSize, iconSize,
|
||||
// /*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/Name/NameDictionary.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzFramework/Visibility/OctreeSystemComponent.h>
|
||||
#include <random>
|
||||
|
||||
@@ -94,6 +95,20 @@ namespace UnitTest
|
||||
AZ::Console* m_console;
|
||||
};
|
||||
|
||||
void ValidateEntryCountEqualsExpectedCount(const IVisibilityScene* visScene, uint32_t expectedEntryCount)
|
||||
{
|
||||
// InsertOrUpdateEntry assumes that updating an existing entry won't change the count
|
||||
// so it doesn't modify the counter used by GetEntryCount.
|
||||
// If an entry is removed from the octree as an unintended side effect of updating an existing entry,
|
||||
// GetEntryCount can't be relied upon to report the actual entry count.
|
||||
// So manually count the entries when using the entry count for validation.
|
||||
uint32_t manualEntryCount = 0;
|
||||
visScene->EnumerateNoCull([&manualEntryCount](const AzFramework::IVisibilityScene::NodeData& nodeData) { manualEntryCount += nodeData.m_entries.size(); });
|
||||
|
||||
EXPECT_EQ(manualEntryCount, expectedEntryCount);
|
||||
EXPECT_EQ(visScene->GetEntryCount(), expectedEntryCount);
|
||||
}
|
||||
|
||||
TEST_F(OctreeTests, InsertDeleteSingleEntry)
|
||||
{
|
||||
AzFramework::VisibilityEntry visEntry;
|
||||
@@ -102,11 +117,11 @@ namespace UnitTest
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry);
|
||||
EXPECT_TRUE(visEntry.m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry.m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry);
|
||||
EXPECT_TRUE(visEntry.m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 0);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 0);
|
||||
|
||||
EXPECT_TRUE(true); //TEST
|
||||
}
|
||||
@@ -121,34 +136,34 @@ namespace UnitTest
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[0]);
|
||||
EXPECT_TRUE(visEntry[0].m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry[0].m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[1]); // This should force a split of the root node
|
||||
EXPECT_TRUE(visEntry[1].m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry[1].m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 2);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 2);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + m_octreeScene->GetChildNodeCount());
|
||||
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[2]); // This should force a split of the roots +/+/+ child node
|
||||
EXPECT_TRUE(visEntry[2].m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry[2].m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 3);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 3);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + (2 * m_octreeScene->GetChildNodeCount()));
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry[2]);
|
||||
EXPECT_TRUE(visEntry[2].m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 2);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 2);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + m_octreeScene->GetChildNodeCount());
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry[1]);
|
||||
EXPECT_TRUE(visEntry[1].m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry[0]);
|
||||
EXPECT_TRUE(visEntry[0].m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 0);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 0);
|
||||
}
|
||||
|
||||
TEST_F(OctreeTests, UpdateSingleEntry)
|
||||
@@ -159,19 +174,19 @@ namespace UnitTest
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry);
|
||||
EXPECT_TRUE(visEntry.m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry.m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
|
||||
visEntry.m_boundingVolume = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.5f), AZ::Vector3(0.5f));
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry);
|
||||
EXPECT_TRUE(visEntry.m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry.m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry);
|
||||
EXPECT_TRUE(visEntry.m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 0);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
}
|
||||
|
||||
@@ -185,19 +200,19 @@ namespace UnitTest
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[0]);
|
||||
EXPECT_TRUE(visEntry[0].m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry[0].m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[1]); // This should force a split of the root node
|
||||
EXPECT_TRUE(visEntry[1].m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry[1].m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 2);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 2);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + m_octreeScene->GetChildNodeCount());
|
||||
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[2]); // This should force a split of the roots +/+/+ child node
|
||||
EXPECT_TRUE(visEntry[2].m_internalNode != nullptr);
|
||||
EXPECT_TRUE(visEntry[2].m_internalNodeIndex == 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 3);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 3);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + (2 * m_octreeScene->GetChildNodeCount()));
|
||||
|
||||
visEntry[1].m_boundingVolume = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.9f), AZ::Vector3(-0.6f));
|
||||
@@ -206,22 +221,22 @@ namespace UnitTest
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[0]);
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[1]);
|
||||
m_octreeScene->InsertOrUpdateEntry(visEntry[2]);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 3);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 3);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + (2 * m_octreeScene->GetChildNodeCount()));
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry[2]);
|
||||
EXPECT_TRUE(visEntry[2].m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 2);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 2);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1 + m_octreeScene->GetChildNodeCount());
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry[1]);
|
||||
EXPECT_TRUE(visEntry[1].m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 1);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 1);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
|
||||
m_octreeScene->RemoveEntry(visEntry[0]);
|
||||
EXPECT_TRUE(visEntry[0].m_internalNode == nullptr);
|
||||
EXPECT_TRUE(m_octreeScene->GetEntryCount() == 0);
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, 0);
|
||||
EXPECT_TRUE(m_octreeScene->GetNodeCount() == 1);
|
||||
}
|
||||
|
||||
@@ -365,4 +380,48 @@ namespace UnitTest
|
||||
AZ::Frustum bound3 = AZ::Frustum(AZ::ViewFrustumAttributes(frustumTransform, 1.0f, 2.0f * atanf(0.5f), 2.6f, 2.9f));
|
||||
EnumerateMultipleEntriesHelper(m_octreeScene, bound1, bound2, bound3);
|
||||
}
|
||||
|
||||
TEST_F(OctreeTests, InsertOrUpdateEntry_OverFillRootNodeWithLargeEntries_EntriesAreNotLost)
|
||||
{
|
||||
// Validate that the octree works if you exceed the max entry count with large entries,
|
||||
// which will overfill the root node since they can't be distributed to child nodes
|
||||
|
||||
// Get the max extents and entries-per-node for the octree
|
||||
AZ::IConsole* console = AZ::Interface<AZ::IConsole>::Get();
|
||||
EXPECT_TRUE(console);
|
||||
|
||||
float maxExtents = 0.0f;
|
||||
AZ::GetValueResult getCvarResult = console->GetCvarValue("bg_octreeMaxWorldExtents", maxExtents);
|
||||
EXPECT_EQ(getCvarResult, AZ::GetValueResult::Success);
|
||||
|
||||
uint32_t maxEntriesPerNode = 0;
|
||||
getCvarResult = console->GetCvarValue("bg_octreeNodeMaxEntries", maxEntriesPerNode);
|
||||
EXPECT_EQ(getCvarResult, AZ::GetValueResult::Success);
|
||||
|
||||
// Create root entries that would exceed the size of the root node
|
||||
AZ::Aabb exceedMaxExtents = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-maxExtents - 1.0f), AZ::Vector3(maxExtents + 1.0f));
|
||||
uint32_t exceedMaxEntriesPerNode = maxEntriesPerNode + 1;
|
||||
|
||||
AzFramework::VisibilityEntry visEntry;
|
||||
visEntry.m_boundingVolume = exceedMaxExtents;
|
||||
AZStd::vector<AzFramework::VisibilityEntry> visEntries(exceedMaxEntriesPerNode, visEntry);
|
||||
|
||||
// Insert them all into the scene
|
||||
for (AzFramework::VisibilityEntry& entry : visEntries)
|
||||
{
|
||||
m_octreeScene->InsertOrUpdateEntry(entry);
|
||||
}
|
||||
|
||||
// Expect all the entries to be in the scene
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, visEntries.size());
|
||||
|
||||
// Update them, without making any actual changes
|
||||
for (AzFramework::VisibilityEntry& entry : visEntries)
|
||||
{
|
||||
m_octreeScene->InsertOrUpdateEntry(entry);
|
||||
}
|
||||
|
||||
// Expect all the entries to be in the scene
|
||||
ValidateEntryCountEqualsExpectedCount(m_octreeScene, visEntries.size());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user