FTI - `global_transform_interpolated()` on demand for invisible nodes
Fixes #107235 Forward port of #107307
Explanation
For visible nodes, the interpolated transform is already cached and calculated in SceneTreeFTI. However, invisible nodes do not calculate interpolated transforms (in order to save processing), thus getting their interpolated transform directly is not possible.
Instead we add mechanism to calculate this interpolated transform on the fly. This will be more expensive than for visible nodes, but can be handy in some situations.
Notes
- The limitation of
_is_vi_visible()toVisualInstancesis getting a little tiresome now, so I have a follow up PR (#107330) to change the calculation and caching ofis_visible_in_tree(), but that should be considered as a separate issue, and this PR will run fine without it.
can confirm this fixes my game and my test cases
A different solution might be to add a flag for visible nodes to interpolate even if they're invisible.
I did consider this first, but if you think about it, the logic for doing this automatically is quite difficult. We also don't want to put the burden of this on the user (if you were thinking manual user flag, as I had considered it in the past).
Bug potential
You would have to know which invisible chain to calculate ahead of time, deal with logic for turning this on and off, it's pretty complex and bug prone. We've had to deal with similar before for client side FTI, and it was a bit of a nightmare .. one of the benefits of the new system is we removed all these bugs.
On demand needs to be available
Essentially the user can call get_global_transform_interpolated() within a frame, and by that time, the SceneTreeFTI has already run, so there is no xform available for the first frame. Effectively it has to be capable of calculating on demand. Now whether it can use this information to mark the chain as worth calculating on the next frame just in case with a timeout, is something for a followup.
Performance considerations
That would save additional processing if they're queried each frame anyway.
I'm not sure it will actually save processing (unless it is called multiple times currently, because result not cached), it just shifts it from on demand to SceneTreeFTI. It may even end being cheaper doing it on demand up the chain, rather than down the chain, because we only have to consider a single parent for each in the chain, whereas downward, there may be e.g. 10,000 child nodes and we only are interested in 1.
Calculating on demand is far simpler conceptually, and should only be done rarely anyway (get_global_transform_interpolated() is advised to use rarely anyway in the documentation, and the need to use it on invisible nodes is even rarer as a use case).
Different PR / Proposal
Imo exploring the approach you mention of getting the SceneTreeFTI to do the work should be left for a follow up PR (if shown to be required in the wild).
Essentially my thoughts are:
- Make it work
- Make it work faster (if there is evidence of performance being a problem)
Thanks!