Change some settings for async physics:

- default to 1 thread
- default to always use defered aabb update, remove option
- always keep a cache of LOS request for at least the current frame.
This decreases number of raycast, especially when a lot of actors are
involved and "NPCs avoid collisions" is on
dont-compose-content
fredzio 4 years ago
parent 83af0402b8
commit 643a64cb2f

@ -137,7 +137,6 @@ namespace MWPhysics
, mNumJobs(0) , mNumJobs(0)
, mRemainingSteps(0) , mRemainingSteps(0)
, mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics")) , mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics"))
, mDeferAabbUpdate(Settings::Manager::getBool("defer aabb update", "Physics"))
, mNewFrame(false) , mNewFrame(false)
, mAdvanceSimulation(false) , mAdvanceSimulation(false)
, mQuit(false) , mQuit(false)
@ -163,8 +162,7 @@ namespace MWPhysics
} }
else else
{ {
mLOSCacheExpiry = -1; mLOSCacheExpiry = 0;
mDeferAabbUpdate = false;
} }
mPreStepBarrier = std::make_unique<Misc::Barrier>(mNumThreads); mPreStepBarrier = std::make_unique<Misc::Barrier>(mNumThreads);
@ -392,7 +390,7 @@ namespace MWPhysics
void PhysicsTaskScheduler::updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate) void PhysicsTaskScheduler::updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate)
{ {
if (!mDeferAabbUpdate || immediate) if (immediate)
{ {
updatePtrAabb(ptr); updatePtrAabb(ptr);
} }
@ -417,8 +415,7 @@ namespace MWPhysics
if (result == mLOSCache.end()) if (result == mLOSCache.end())
{ {
req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get()); req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get());
if (mLOSCacheExpiry >= 0) mLOSCache.push_back(req);
mLOSCache.push_back(req);
return req.mResult; return req.mResult;
} }
result->mAge = 0; result->mAge = 0;
@ -508,8 +505,7 @@ namespace MWPhysics
} }
} }
if (mLOSCacheExpiry >= 0) refreshLOSCache();
refreshLOSCache();
mPostSimBarrier->wait([this] { afterPostSim(); }); mPostSimBarrier->wait([this] { afterPostSim(); });
} }
} }
@ -594,8 +590,7 @@ namespace MWPhysics
void PhysicsTaskScheduler::afterPreStep() void PhysicsTaskScheduler::afterPreStep()
{ {
if (mDeferAabbUpdate) updateAabbs();
updateAabbs();
if (!mRemainingSteps) if (!mRemainingSteps)
return; return;
for (auto& data : mActorsFrameData) for (auto& data : mActorsFrameData)
@ -619,7 +614,6 @@ namespace MWPhysics
void PhysicsTaskScheduler::afterPostSim() void PhysicsTaskScheduler::afterPostSim()
{ {
mNewFrame = false; mNewFrame = false;
if (mLOSCacheExpiry >= 0)
{ {
std::unique_lock lock(mLOSCacheMutex); std::unique_lock lock(mLOSCacheMutex);
mLOSCache.erase( mLOSCache.erase(

@ -90,7 +90,6 @@ namespace MWPhysics
int mNumJobs; int mNumJobs;
int mRemainingSteps; int mRemainingSteps;
int mLOSCacheExpiry; int mLOSCacheExpiry;
bool mDeferAabbUpdate;
bool mNewFrame; bool mNewFrame;
bool mAdvanceSimulation; bool mAdvanceSimulation;
bool mThreadSafeBullet; bool mThreadSafeBullet;

@ -6,7 +6,7 @@ async num threads
:Type: integer :Type: integer
:Range: >= 0 :Range: >= 0
:Default: 0 :Default: 1
Determines how many threads will be spawned to compute physics update in the background (that is, process actors movement). A value of 0 means that the update will be performed in the main thread. Determines how many threads will be spawned to compute physics update in the background (that is, process actors movement). A value of 0 means that the update will be performed in the main thread.
A value greater than 1 requires the Bullet library be compiled with multithreading support. If that's not the case, a warning will be written in ``openmw.log`` and a value of 1 will be used. A value greater than 1 requires the Bullet library be compiled with multithreading support. If that's not the case, a warning will be written in ``openmw.log`` and a value of 1 will be used.
@ -19,19 +19,9 @@ lineofsight keep inactive cache
:Default: 0 :Default: 0
The line of sight determines if 2 actors can see each other (without taking into account game mechanics such as invisibility or sneaking). It is used by some scripts (the getLOS function), by the AI (to determine if an actor should start combat or chase an opponent) and for functionnalities such as greetings or turning NPC head toward an object. The line of sight determines if 2 actors can see each other (without taking into account game mechanics such as invisibility or sneaking). It is used by some scripts (the getLOS function), by the AI (to determine if an actor should start combat or chase an opponent) and for functionnalities such as greetings or turning NPC head toward an object.
This parameters determine for how long a cache of request should be kept warm. It depends on :ref:`async num threads` being > 0, otherwise a value of -1 will be used. If a request is not found in the cache, it is always fulfilled immediately. In case Bullet is compiled without multithreading support, non-cached requests involve blocking the async thread(s), which might hurt performance. This parameters determine for how long a cache of request should be kept warm.
A value of -1 means no caching. A value of 0 means that the cache is kept only for the current frame, that is if a request is done 2 times in the same frame, the second request will be in cache.
A value of 0 means that for as long as a request is made (after the first one), it will be preemptively "refreshed" in the async thread, without blocking neither the main thread nor the async thread.
Any value > 0 is the number of frames for which the values are kept in cache even if the results was not requested again. Any value > 0 is the number of frames for which the values are kept in cache even if the results was not requested again.
If Bullet is compiled with multithreading support, requests are non blocking, it is better to set this parameter to -1. If :ref:`async num threads` is 0, a value of 0 will be used.
If a request is not found in the cache, it is always fulfilled immediately. In case Bullet is compiled without multithreading support, non-cached requests involve blocking the async thread, which might hurt performance.
defer aabb update If Bullet is compiled with multithreading support, requests are non blocking, it is better to set this parameter to 0.
-----------------
:Type: boolean
:Range: True/False
:Default: True
Axis-aligned bounding box (aabb for short) are used by Bullet for collision detection. They should be updated anytime a physical object is modified (for instance moved) for collision detection to be correct.
This parameter control wether the update should be done as soon as the object is modified (the default), which involves blocking the async thread(s), or queue the modifications to update them as a batch before the collision detections. It depends on :ref:`async num threads` being > 0, otherwise it will be disabled.
Disabling this parameter is intended as an aid for debugging collisions detection issues.

@ -985,16 +985,12 @@ enable indoor shadows = true
# Set the number of background threads used for physics. # Set the number of background threads used for physics.
# If no background threads are used, physics calculations are processed in the main thread # If no background threads are used, physics calculations are processed in the main thread
# and the settings below have no effect. # and the settings below have no effect.
async num threads = 0 async num threads = 1
# Set the number of frames an inactive line-of-sight request will be kept # Set the number of frames an inactive line-of-sight request will be kept
# refreshed in the background physics thread cache. # refreshed in the background physics thread cache.
# If this is set to -1, line-of-sight requests are never cached.
lineofsight keep inactive cache = 0 lineofsight keep inactive cache = 0
# Defer bounding boxes update until collision detection.
defer aabb update = true
[Models] [Models]
# Attempt to load any valid NIF file regardless of its version and track the progress. # Attempt to load any valid NIF file regardless of its version and track the progress.

Loading…
Cancel
Save