Hello,
I am wondering how I can safely do shape sweeps (i.e. a sphere query) on the latest state of the physics scene, if I am not on the game thread but on the physics thread? For example, in an async component tick or in one of the *_Internal methods of ISimCallbackObject or IRewindCallback.
I am aware of the UKismetSystemLibrary functions, UWorld::OverlapMultiByChannel, etc. They are not what I am looking for as they use FPhysicsInterface and are designed to be called from the game thread. Even if they work, I assume they would not hold the very latest state of the scene but only the state that has been pushed to the game thread.
I am on the .
Thanks in advance.
Found two solutions, posting here so others can do the same.
Basically the problem is in the function GetThreadQueryContext() in SceneQuery.cpp. On line 330 it says “//TODO: need a way to know we are on a physics thread task (this isn’t supported yet)”.
Solution one is to replace the line below that comment with the following:
if (IsInGameThread()) {
return EThreadQueryContext::GTData;
}
else {
return EThreadQueryContext::PTOnlyData;
}
The above assumes that any other thread than the game thread calling it will be the physics thread. I think this is a good assumption as it would be bad practice anyway to query the game thread data from a third thread.
With the fix above, the regular functions such as UWorld::SweepSingleByChannel will function properly both when called from the game thread and from the physics thread, and they will always query the appropriate physics state (the interpolated state on the GT and the most recent state on the PT).
Option two is more involving but would not require engine changes which might be more suitable to some people. You need to get the internal acceleration structure from the physics scene solver with GetInternalAccelerationStructure_Internal(), cast that to SQAccelerator and call the Sweep or Overlap functions. Setting up the required data (including collision filters and parameters) was much more involving so I went with the engine modification above instead. If anyone is interested in taking this approach, I suggest checking out the LowLevelOverlapImp() functions and similar in SceneQueryLowLevel.cpp. The problem with this approach is mainly that you have to create your own CollisionQueryFilterCallback as the one they use internally is not available. Also many of the helper functions are not available so you might have to manually set up a lot of structures and boilerplate.
3 Likes