SurfaceTagWeights optimization (#7436)
* Add comparison operators to SurfaceTagWeight. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed AddSurfaceTagWeight to always combine weights. This simplifies the API a bit and defines the behavior if someone ever tries to add a duplicate tag. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for measuring the performance-critical APIs. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed SurfaceTagWeights to a fixed_vector. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
This commit is contained in:
@@ -259,7 +259,7 @@ namespace SurfaceData
|
||||
if (DoRayTrace(position, queryPointOnly, hitPosition, hitNormal))
|
||||
{
|
||||
// If the query point collides with the volume, add all our modifier tags with a weight of 1.0f.
|
||||
weights.AddSurfaceWeightsIfGreater(m_configuration.m_modifierTags, 1.0f);
|
||||
weights.AddSurfaceTagWeights(m_configuration.m_modifierTags, 1.0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace SurfaceData
|
||||
if (m_shapeBounds.Contains(position) && shape->IsPointInside(position))
|
||||
{
|
||||
// If the point is inside our shape, add all our modifier tags with a weight of 1.0f.
|
||||
weights.AddSurfaceWeightsIfGreater(m_configuration.m_modifierTags, 1.0f);
|
||||
weights.AddSurfaceTagWeights(m_configuration.m_modifierTags, 1.0f);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,28 +14,21 @@ namespace SurfaceData
|
||||
void SurfaceTagWeights::AssignSurfaceTagWeights(const AzFramework::SurfaceData::SurfaceTagWeightList& weights)
|
||||
{
|
||||
m_weights.clear();
|
||||
m_weights.reserve(weights.size());
|
||||
for (auto& weight : weights)
|
||||
{
|
||||
m_weights.emplace(weight.m_surfaceType, weight.m_weight);
|
||||
AddSurfaceTagWeight(weight.m_surfaceType, weight.m_weight);
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceTagWeights::AssignSurfaceTagWeights(const SurfaceTagVector& tags, float weight)
|
||||
{
|
||||
m_weights.clear();
|
||||
m_weights.reserve(tags.size());
|
||||
for (auto& tag : tags)
|
||||
{
|
||||
m_weights[tag] = weight;
|
||||
AddSurfaceTagWeight(tag.operator AZ::Crc32(), weight);
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceTagWeights::AddSurfaceTagWeight(const AZ::Crc32 tag, const float value)
|
||||
{
|
||||
m_weights[tag] = value;
|
||||
}
|
||||
|
||||
void SurfaceTagWeights::Clear()
|
||||
{
|
||||
m_weights.clear();
|
||||
@@ -52,7 +45,7 @@ namespace SurfaceData
|
||||
weights.reserve(m_weights.size());
|
||||
for (auto& weight : m_weights)
|
||||
{
|
||||
weights.emplace_back(weight.first, weight.second);
|
||||
weights.emplace_back(weight);
|
||||
}
|
||||
return weights;
|
||||
}
|
||||
@@ -65,17 +58,8 @@ namespace SurfaceData
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& weight : m_weights)
|
||||
{
|
||||
auto rhsWeight = rhs.m_weights.find(weight.first);
|
||||
if ((rhsWeight == rhs.m_weights.end()) || (rhsWeight->second != weight.second))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All the entries matched, and the lists are the same size, so they're equal.
|
||||
return true;
|
||||
// The lists are stored in sorted order, so we can compare every entry in order for equivalence.
|
||||
return (m_weights == rhs.m_weights);
|
||||
}
|
||||
|
||||
bool SurfaceTagWeights::SurfaceWeightsAreEqual(const AzFramework::SurfaceData::SurfaceTagWeightList& compareWeights) const
|
||||
@@ -92,7 +76,7 @@ namespace SurfaceData
|
||||
compareWeights.begin(), compareWeights.end(),
|
||||
[weight](const AzFramework::SurfaceData::SurfaceTagWeight& compareWeight) -> bool
|
||||
{
|
||||
return (weight.first == compareWeight.m_surfaceType) && (weight.second == compareWeight.m_weight);
|
||||
return (weight == compareWeight);
|
||||
});
|
||||
|
||||
// If we didn't find a match, they're not equal.
|
||||
@@ -119,9 +103,9 @@ namespace SurfaceData
|
||||
|
||||
bool SurfaceTagWeights::HasValidTags() const
|
||||
{
|
||||
for (const auto& sourceTag : m_weights)
|
||||
for (const auto& weight : m_weights)
|
||||
{
|
||||
if (sourceTag.first != Constants::s_unassignedTagCrc)
|
||||
if (weight.m_surfaceType != Constants::s_unassignedTagCrc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -129,9 +113,9 @@ namespace SurfaceData
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SurfaceTagWeights::HasMatchingTag(const AZ::Crc32& sampleTag) const
|
||||
bool SurfaceTagWeights::HasMatchingTag(AZ::Crc32 sampleTag) const
|
||||
{
|
||||
return m_weights.find(sampleTag) != m_weights.end();
|
||||
return FindTag(sampleTag) != m_weights.end();
|
||||
}
|
||||
|
||||
bool SurfaceTagWeights::HasAnyMatchingTags(const SurfaceTagVector& sampleTags) const
|
||||
@@ -147,10 +131,10 @@ namespace SurfaceData
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SurfaceTagWeights::HasMatchingTag(const AZ::Crc32& sampleTag, float weightMin, float weightMax) const
|
||||
bool SurfaceTagWeights::HasMatchingTag(AZ::Crc32 sampleTag, float weightMin, float weightMax) const
|
||||
{
|
||||
auto maskItr = m_weights.find(sampleTag);
|
||||
return maskItr != m_weights.end() && weightMin <= maskItr->second && weightMax >= maskItr->second;
|
||||
auto weightEntry = FindTag(sampleTag);
|
||||
return weightEntry != m_weights.end() && weightMin <= weightEntry->m_weight && weightMax >= weightEntry->m_weight;
|
||||
}
|
||||
|
||||
bool SurfaceTagWeights::HasAnyMatchingTags(const SurfaceTagVector& sampleTags, float weightMin, float weightMax) const
|
||||
@@ -166,7 +150,25 @@ namespace SurfaceData
|
||||
return false;
|
||||
}
|
||||
|
||||
const AzFramework::SurfaceData::SurfaceTagWeight* SurfaceTagWeights::FindTag(AZ::Crc32 tag) const
|
||||
{
|
||||
for (auto weightItr = m_weights.begin(); weightItr != m_weights.end(); ++weightItr)
|
||||
{
|
||||
if (weightItr->m_surfaceType == tag)
|
||||
{
|
||||
// Found the tag, return a pointer to the entry.
|
||||
return weightItr;
|
||||
}
|
||||
else if (weightItr->m_surfaceType > tag)
|
||||
{
|
||||
// Our list is stored in sorted order by surfaceType, so early-out if our values get too high.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The tag wasn't found, so return end().
|
||||
return m_weights.end();
|
||||
}
|
||||
|
||||
|
||||
SurfacePointList::SurfacePointList(AZStd::initializer_list<const AzFramework::SurfaceData::SurfacePoint> surfacePoints)
|
||||
@@ -192,7 +194,7 @@ namespace SurfaceData
|
||||
if (m_surfacePositionList[index].IsClose(position) && m_surfaceNormalList[index].IsClose(normal))
|
||||
{
|
||||
// consolidate points with similar attributes by adding masks/weights to the similar point instead of adding a new one.
|
||||
m_surfaceWeightsList[index].AddSurfaceWeightsIfGreater(masks);
|
||||
m_surfaceWeightsList[index].AddSurfaceTagWeights(masks);
|
||||
return;
|
||||
}
|
||||
else if (m_surfacePositionList[index].GetZ() < position.GetZ())
|
||||
|
||||
Reference in New Issue
Block a user