Unlike what I expected, the osgUtil::UpdateVisitor is set to traverse all children (not only active children). The FrameSwitch was thus traversing both RigGeometries part of the double-buffering scheme, rather than only the one active in the current frame.
Problem with debce0fb80 is the crashed process won't be killed until the user accepts the message box, and it's harder to get to the message box when the window is in full screen or the cursor is locked.
This change fixes a random X server lock-up that I get about 1 in 10 times when a crash is caught. I'm presuming it's an X server bug since faulty applications shouldn't be able to crash or freeze the X server under any circumstances.
The resizing of LTEX store to the correct number of plugins was done in the load() method, but the load method won't be called if a plugin contains LAND records but doesn't contain LTEX records. For such plugins the Store<ESM::LandTexture>::search() function would then fail an assertion.
This helps avoid a lock during the movie player's read method, since it needs
to sync with the current playback position which would otherwise need to get
the movie decoder's current position.
There is no change in behaviour since we were using the C locale.
The locale-aware tolower is much slower than the locale-unaware one. At least on Linux/GCC it calls dynamic_cast's, and is overall slower by an order of magnitude.
Use pointers as map keys instead of string IDs. Resolves a nasty performance bottleneck on functions like hasCommonDisease() that previously had to look up all contained spells from the ESM store on every call. hasCommonDisease() is called hundreds of times per frame by the AI target update since it's used to calculate target disposition.
The total cost of hasCommonDisease() was 2.7% of the frame loop, now it's negligible.