java-topology/defects/ogre/patch/ogre-0003-ribbontrail-chain-reverse-map.patch

57 lines
2.2 KiB
Diff

# UNDF: UNDF-2026-000000195
--- a/OgreMain/include/OgreRibbonTrail.h
+++ b/OgreMain/include/OgreRibbonTrail.h
@@ -27,6 +27,7 @@ THE SOFTWARE.
#pragma once
+#include <unordered_map>
#include "OgreBillboardChain.h"
#include "OgreNode.h"
#include "OgreIteratorWrappers.h"
@@ -93,6 +94,8 @@ namespace Ogre {
NodeList mNodeList;
typedef std::vector<size_t> IndexVector;
IndexVector mNodeToChainSegment;
+ /// Reverse map: chain segment index → node pointer (O(1) lookup in clearChain)
+ std::unordered_map<size_t, Node*> mChainToNodeMap;
IndexVector mFreeChains;
typedef std::map<const Node*, size_t> NodeToChainSegmentMap;
NodeToChainSegmentMap mNodeToSegMap;
--- a/OgreMain/src/OgreRibbonTrail.cpp
+++ b/OgreMain/src/OgreRibbonTrail.cpp
@@ -97,6 +97,7 @@ namespace Ogre {
mNodeToChainSegment.push_back(chainIndex);
mNodeToSegMap[n] = chainIndex;
+ mChainToNodeMap[chainIndex] = n;
// initialise the chain
resetTrail(chainIndex, n);
@@ -130,6 +131,7 @@ namespace Ogre {
size_t chainIndex = *mi;
BillboardChain::clearChain(chainIndex);
// mark as free now
mFreeChains.push_back(chainIndex);
+ mChainToNodeMap.erase(chainIndex);
mNodeToSegMap.erase(n);
mNodeList.erase(i);
mNodeToChainSegment.erase(mi);
@@ -199,12 +201,12 @@ namespace Ogre {
void RibbonTrail::clearChain(size_t chainIndex)
{
BillboardChain::clearChain(chainIndex);
- // Reset if we are tracking for this chain
- IndexVector::iterator i = std::find(mNodeToChainSegment.begin(),
- mNodeToChainSegment.end(), chainIndex); // O(N)
- if (i != mNodeToChainSegment.end())
- {
- size_t nodeIndex = std::distance(mNodeToChainSegment.begin(), i);
- resetTrail(*i, mNodeList[nodeIndex]);
+ // O(1) reverse lookup — replaced O(N) parallel-vector scan
+ auto it = mChainToNodeMap.find(chainIndex);
+ if (it != mChainToNodeMap.end())
+ {
+ resetTrail(chainIndex, it->second);
}
}