More fixes to migration, plus some quality of life fixes to TimeoutQueue to allow lambda based handlers and a quick fix to OctreeSystemComponent to more gracefully handle enumerate calls that lie outside the vis system bounds
Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
@@ -14,9 +14,8 @@ namespace AzFramework
|
||||
{
|
||||
AZ_CVAR(bool, bg_octreeUseQuadtree, false, nullptr, AZ::ConsoleFunctorFlags::ReadOnly, "If set to true, the visibility octrees will degenerate to a quadtree split along the X/Y plane");
|
||||
AZ_CVAR(float, bg_octreeMaxWorldExtents, 16384.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum supported world size by the world octreeSystemComponent");
|
||||
AZ_CVAR(uint32_t, bg_octreeNodeMaxEntries, 64, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum number of entries to allow in any node before forcing a split");
|
||||
AZ_CVAR(uint32_t, bg_octreeNodeMinEntries, 32, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum number of entries to allow in a node resulting from a merge operation");
|
||||
|
||||
AZ_CVAR(uint32_t, bg_octreeNodeMaxEntries, 64, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum number of entries to allow in any node before forcing a split");
|
||||
AZ_CVAR(uint32_t, bg_octreeNodeMinEntries, 32, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum number of entries to allow in a node resulting from a merge operation");
|
||||
|
||||
static uint32_t GetChildNodeCount()
|
||||
{
|
||||
@@ -25,14 +24,12 @@ namespace AzFramework
|
||||
return (bg_octreeUseQuadtree) ? QuadtreeNodeChildCount : OctreeNodeChildCount;
|
||||
}
|
||||
|
||||
|
||||
OctreeNode::OctreeNode(const AZ::Aabb& bounds)
|
||||
: m_bounds(bounds)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
OctreeNode::OctreeNode(OctreeNode&& rhs)
|
||||
: m_bounds(rhs.m_bounds)
|
||||
, m_parent(rhs.m_parent)
|
||||
@@ -46,7 +43,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OctreeNode& OctreeNode::operator=(OctreeNode&& rhs)
|
||||
{
|
||||
m_bounds = rhs.m_bounds;
|
||||
@@ -63,7 +59,6 @@ namespace AzFramework
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Insert(OctreeScene& octreeScene, VisibilityEntry* entry)
|
||||
{
|
||||
AZ_Assert(entry->m_internalNode == nullptr, "Double-insertion: Insert invoked for an entry already bound to the OctreeScene");
|
||||
@@ -98,7 +93,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Update(OctreeScene& octreeScene, VisibilityEntry* entry)
|
||||
{
|
||||
AZ_Assert(entry->m_internalNode == this, "Update invoked for an entry bound to a different OctreeNode");
|
||||
@@ -129,7 +123,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Remove(OctreeScene& octreeScene, VisibilityEntry* entry)
|
||||
{
|
||||
AZ_Assert(entry->m_internalNode == this, "Remove invoked for an entry bound to a different OctreeNode");
|
||||
@@ -152,25 +145,30 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Enumerate(const AZ::Aabb& aabb, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
EnumerateHelper(aabb, callback);
|
||||
if (AZ::ShapeIntersection::Overlaps(aabb, m_bounds))
|
||||
{
|
||||
EnumerateHelper(aabb, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Enumerate(const AZ::Sphere& sphere, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
EnumerateHelper(sphere, callback);
|
||||
if (AZ::ShapeIntersection::Overlaps(sphere, m_bounds))
|
||||
{
|
||||
EnumerateHelper(sphere, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Enumerate(const AZ::Frustum& frustum, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
EnumerateHelper(frustum, callback);
|
||||
if (AZ::ShapeIntersection::Overlaps(frustum, m_bounds))
|
||||
{
|
||||
EnumerateHelper(frustum, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::EnumerateNoCull(const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
// Invoke the callback for the current node
|
||||
@@ -190,25 +188,21 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const AZStd::vector<VisibilityEntry*>& OctreeNode::GetEntries() const
|
||||
{
|
||||
return m_entries;
|
||||
}
|
||||
|
||||
|
||||
OctreeNode* OctreeNode::GetChildren() const
|
||||
{
|
||||
return m_children;
|
||||
}
|
||||
|
||||
|
||||
bool OctreeNode::IsLeaf() const
|
||||
{
|
||||
return m_children == nullptr;
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::TryMerge(OctreeScene& octreeScene)
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -236,7 +230,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void OctreeNode::EnumerateHelper(const T& boundingVolume, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
@@ -262,7 +255,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Split(OctreeScene& octreeScene)
|
||||
{
|
||||
AZ_Assert(m_children == nullptr, "Split invoked on an octreeScene node that has already been split");
|
||||
@@ -312,7 +304,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeNode::Merge(OctreeScene& octreeScene)
|
||||
{
|
||||
AZ_Assert(m_children != nullptr, "Merge invoked on an octreeScene node that does not have children");
|
||||
@@ -371,7 +362,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::RemoveEntry(VisibilityEntry& entry)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::shared_mutex> lock(m_sharedMutex);
|
||||
@@ -382,35 +372,30 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::Enumerate(const AZ::Aabb& aabb, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
|
||||
m_root.Enumerate(aabb, callback);
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::Enumerate(const AZ::Sphere& sphere, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
|
||||
m_root.Enumerate(sphere, callback);
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::Enumerate(const AZ::Frustum& frustum, const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
|
||||
m_root.Enumerate(frustum, callback);
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::EnumerateNoCull(const IVisibilityScene::EnumerateCallback& callback) const
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
|
||||
m_root.EnumerateNoCull(callback);
|
||||
}
|
||||
|
||||
|
||||
uint32_t OctreeScene::GetEntryCount() const
|
||||
{
|
||||
return m_entryCount;
|
||||
@@ -421,26 +406,22 @@ namespace AzFramework
|
||||
return m_nodeCount;
|
||||
}
|
||||
|
||||
|
||||
uint32_t OctreeScene::GetFreeNodeCount() const
|
||||
{
|
||||
// Each entry represents GetChildNodeCount() nodes
|
||||
return aznumeric_cast<uint32_t>(m_freeOctreeNodes.size() * GetChildNodeCount());
|
||||
}
|
||||
|
||||
|
||||
uint32_t OctreeScene::GetPageCount() const
|
||||
{
|
||||
return aznumeric_cast<uint32_t>(m_nodeCache.size());
|
||||
}
|
||||
|
||||
|
||||
uint32_t OctreeScene::GetChildNodeCount() const
|
||||
{
|
||||
return AzFramework::GetChildNodeCount();
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::DumpStats()
|
||||
{
|
||||
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::EntryCount = %u", GetName().GetCStr(), GetEntryCount());
|
||||
@@ -450,21 +431,18 @@ namespace AzFramework
|
||||
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::ChildNodeCount = %u", GetName().GetCStr(), GetChildNodeCount());
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t CreateNodeIndex(uint32_t page, uint32_t offset)
|
||||
{
|
||||
AZ_Assert(page <= 0xFFFF && offset <= 0xFFFF, "Out of range values passed to CreateNodeIndex");
|
||||
return (page << 16) | offset;
|
||||
}
|
||||
|
||||
|
||||
static inline void ExtractPageAndOffsetFromIndex(uint32_t index, uint32_t& page, uint32_t& offset)
|
||||
{
|
||||
offset = index & 0x0000FFFF;
|
||||
page = index >> 16;
|
||||
}
|
||||
|
||||
|
||||
uint32_t OctreeScene::AllocateChildNodes()
|
||||
{
|
||||
const uint32_t childCount = GetChildNodeCount();
|
||||
@@ -508,14 +486,12 @@ namespace AzFramework
|
||||
return CreateNodeIndex(nextChildPage, nextChildOffset);
|
||||
}
|
||||
|
||||
|
||||
void OctreeScene::ReleaseChildNodes(uint32_t nodeIndex)
|
||||
{
|
||||
m_nodeCount -= GetChildNodeCount();
|
||||
m_freeOctreeNodes.push(nodeIndex);
|
||||
}
|
||||
|
||||
|
||||
OctreeNode* OctreeScene::GetChildNodesAtIndex(uint32_t nodeIndex) const
|
||||
{
|
||||
uint32_t childPage;
|
||||
@@ -524,7 +500,6 @@ namespace AzFramework
|
||||
return &(*m_nodeCache[childPage])[childOffset];
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
@@ -534,19 +509,16 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("OctreeService"));
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("OctreeService"));
|
||||
}
|
||||
|
||||
|
||||
OctreeSystemComponent::OctreeSystemComponent()
|
||||
{
|
||||
AZ::Interface<IVisibilitySystem>::Register(this);
|
||||
@@ -555,7 +527,6 @@ namespace AzFramework
|
||||
m_defaultScene = aznew OctreeScene(AZ::Name("DefaultVisibilityScene"));
|
||||
}
|
||||
|
||||
|
||||
OctreeSystemComponent::~OctreeSystemComponent()
|
||||
{
|
||||
AZ_Assert(m_scenes.empty(), "All IVisibilityScenes must be destroyed before shutdown");
|
||||
@@ -566,13 +537,11 @@ namespace AzFramework
|
||||
AZ::Interface<IVisibilitySystem>::Unregister(this);
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::Activate()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::Deactivate()
|
||||
{
|
||||
;
|
||||
@@ -591,7 +560,6 @@ namespace AzFramework
|
||||
return newScene;
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::DestroyVisibilityScene(IVisibilityScene* visScene)
|
||||
{
|
||||
for (auto iter = m_scenes.begin(); iter != m_scenes.end(); ++iter)
|
||||
@@ -606,7 +574,6 @@ namespace AzFramework
|
||||
AZ_Assert(false, "visScene[\"%s\"] not found in the OctreeSystemComponent", visScene->GetName().GetCStr());
|
||||
}
|
||||
|
||||
|
||||
IVisibilityScene* OctreeSystemComponent::FindVisibilityScene(const AZ::Name& sceneName)
|
||||
{
|
||||
for (OctreeScene* scene : m_scenes)
|
||||
@@ -619,7 +586,6 @@ namespace AzFramework
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void OctreeSystemComponent::DumpStats([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
for (OctreeScene* scene : m_scenes)
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace AzNetworking
|
||||
m_timeoutItemMap.erase(timeoutId);
|
||||
}
|
||||
|
||||
void TimeoutQueue::UpdateTimeouts(ITimeoutHandler& timeoutHandler, int32_t maxTimeouts)
|
||||
void TimeoutQueue::UpdateTimeouts(const TimeoutHandler& timeoutHandler, int32_t maxTimeouts)
|
||||
{
|
||||
int32_t numTimeouts = 0;
|
||||
if (maxTimeouts < 0)
|
||||
@@ -103,7 +103,7 @@ namespace AzNetworking
|
||||
|
||||
// By this point, the item is definitely timed out
|
||||
// Invoke the timeout function to see how to proceed
|
||||
const TimeoutResult result = timeoutHandler.HandleTimeout(mapItem);
|
||||
const TimeoutResult result = timeoutHandler(mapItem);
|
||||
|
||||
if (result == TimeoutResult::Refresh)
|
||||
{
|
||||
@@ -122,4 +122,10 @@ namespace AzNetworking
|
||||
m_timeoutItemMap.erase(itemTimeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeoutQueue::UpdateTimeouts(ITimeoutHandler& timeoutHandler, int32_t maxTimeouts)
|
||||
{
|
||||
TimeoutHandler handler([&timeoutHandler](TimeoutQueue::TimeoutItem& item) { return timeoutHandler.HandleTimeout(item); });
|
||||
UpdateTimeouts(handler, maxTimeouts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,12 @@ namespace AzNetworking
|
||||
//! @param timeoutId the identifier of the item to remove
|
||||
void RemoveItem(TimeoutId timeoutId);
|
||||
|
||||
//! Updates timeouts for all items, invokes the provided timeout functor if required.
|
||||
//! @param timeoutHandler lambda to invoke for all timeouts
|
||||
//! @param maxTimeouts the maximum number of timeouts to process before breaking iteration
|
||||
using TimeoutHandler = AZStd::function<TimeoutResult(TimeoutQueue::TimeoutItem&)>;
|
||||
void UpdateTimeouts(const TimeoutHandler& timeoutHandler, int32_t maxTimeouts = -1);
|
||||
|
||||
//! Updates timeouts for all items, invokes timeout handlers if required.
|
||||
//! @param timeoutHandler listener instance to call back on for timeouts
|
||||
//! @param maxTimeouts the maximum number of timeouts to process before breaking iteration
|
||||
|
||||
Reference in New Issue
Block a user