2022-10-08 12:36:45 +02:00
|
|
|
#include "mtphysics.hpp"
|
|
|
|
|
2022-09-07 01:55:51 +02:00
|
|
|
#include <cassert>
|
2022-01-29 05:04:32 +01:00
|
|
|
#include <functional>
|
2022-07-12 14:53:06 +02:00
|
|
|
#include <mutex>
|
|
|
|
#include <optional>
|
|
|
|
#include <shared_mutex>
|
2023-02-12 14:51:46 +01:00
|
|
|
#include <stdexcept>
|
2022-09-07 01:55:51 +02:00
|
|
|
#include <variant>
|
2022-01-29 05:04:32 +01:00
|
|
|
|
2020-10-19 21:26:21 +02:00
|
|
|
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
|
|
|
|
2020-11-20 13:11:53 +01:00
|
|
|
#include <osg/Stats>
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
#include "components/debug/debuglog.hpp"
|
|
|
|
#include "components/misc/convert.hpp"
|
|
|
|
#include "components/settings/settings.hpp"
|
|
|
|
#include <components/misc/barrier.hpp>
|
2022-06-26 16:42:29 +02:00
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
2022-07-16 16:37:31 +02:00
|
|
|
#include "../mwmechanics/creaturestats.hpp"
|
|
|
|
|
2021-03-26 23:45:56 +01:00
|
|
|
#include "../mwrender/bulletdebugdraw.hpp"
|
2022-07-16 16:37:31 +02:00
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwbase/world.hpp"
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
#include "actor.hpp"
|
2020-12-27 22:16:11 +00:00
|
|
|
#include "contacttestwrapper.h"
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
#include "movementsolver.hpp"
|
|
|
|
#include "object.hpp"
|
|
|
|
#include "physicssystem.hpp"
|
2020-10-23 20:27:07 +02:00
|
|
|
#include "projectile.hpp"
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
namespace MWPhysics
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
namespace
|
2021-10-05 15:43:21 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
template <class Mutex>
|
|
|
|
std::optional<std::unique_lock<Mutex>> makeExclusiveLock(Mutex& mutex, LockingPolicy lockingPolicy)
|
2022-07-12 14:53:06 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
if (lockingPolicy == LockingPolicy::NoLocks)
|
|
|
|
return {};
|
|
|
|
return std::unique_lock(mutex);
|
2022-07-12 14:53:06 +02:00
|
|
|
}
|
2021-10-05 15:43:21 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
/// @brief A scoped lock that is either exclusive or inexistent depending on configuration
|
|
|
|
template <class Mutex>
|
|
|
|
class MaybeExclusiveLock
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// @param mutex a mutex
|
|
|
|
/// @param threadCount decide wether the excluse lock will be taken
|
|
|
|
explicit MaybeExclusiveLock(Mutex& mutex, LockingPolicy lockingPolicy)
|
|
|
|
: mImpl(makeExclusiveLock(mutex, lockingPolicy))
|
|
|
|
{
|
|
|
|
}
|
2021-10-05 15:43:21 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
private:
|
|
|
|
std::optional<std::unique_lock<Mutex>> mImpl;
|
|
|
|
};
|
2022-07-12 14:53:06 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
template <class Mutex>
|
|
|
|
std::optional<std::shared_lock<Mutex>> makeSharedLock(Mutex& mutex, LockingPolicy lockingPolicy)
|
2022-07-12 14:53:06 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
if (lockingPolicy == LockingPolicy::NoLocks)
|
|
|
|
return {};
|
|
|
|
return std::shared_lock(mutex);
|
2022-07-12 14:53:06 +02:00
|
|
|
}
|
2021-10-05 15:43:21 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
/// @brief A scoped lock that is either shared or inexistent depending on configuration
|
|
|
|
template <class Mutex>
|
|
|
|
class MaybeSharedLock
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// @param mutex a shared mutex
|
|
|
|
/// @param threadCount decide wether the shared lock will be taken
|
|
|
|
explicit MaybeSharedLock(Mutex& mutex, LockingPolicy lockingPolicy)
|
|
|
|
: mImpl(makeSharedLock(mutex, lockingPolicy))
|
|
|
|
{
|
|
|
|
}
|
2021-10-05 15:43:21 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
private:
|
|
|
|
std::optional<std::shared_lock<Mutex>> mImpl;
|
|
|
|
};
|
2022-07-12 14:53:06 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
template <class Mutex>
|
|
|
|
std::variant<std::monostate, std::unique_lock<Mutex>, std::shared_lock<Mutex>> makeLock(
|
|
|
|
Mutex& mutex, LockingPolicy lockingPolicy)
|
2022-07-12 14:53:06 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
switch (lockingPolicy)
|
|
|
|
{
|
|
|
|
case LockingPolicy::NoLocks:
|
|
|
|
return std::monostate{};
|
|
|
|
case LockingPolicy::ExclusiveLocksOnly:
|
|
|
|
return std::unique_lock(mutex);
|
|
|
|
case LockingPolicy::AllowSharedLocks:
|
|
|
|
return std::shared_lock(mutex);
|
|
|
|
};
|
|
|
|
|
|
|
|
throw std::runtime_error("Unsupported LockingPolicy: "
|
|
|
|
+ std::to_string(static_cast<std::underlying_type_t<LockingPolicy>>(lockingPolicy)));
|
2022-07-12 14:53:06 +02:00
|
|
|
}
|
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
/// @brief A scoped lock that is either shared, exclusive or inexistent depending on configuration
|
|
|
|
template <class Mutex>
|
|
|
|
class MaybeLock
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// @param mutex a shared mutex
|
|
|
|
/// @param threadCount decide wether the lock will be shared, exclusive or inexistent
|
|
|
|
explicit MaybeLock(Mutex& mutex, LockingPolicy lockingPolicy)
|
|
|
|
: mImpl(makeLock(mutex, lockingPolicy))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::variant<std::monostate, std::unique_lock<Mutex>, std::shared_lock<Mutex>> mImpl;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
namespace
|
|
|
|
{
|
2021-07-22 00:08:44 +02:00
|
|
|
bool isUnderWater(const MWPhysics::ActorFrameData& actorData)
|
|
|
|
{
|
|
|
|
return actorData.mPosition.z() < actorData.mSwimLevel;
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:15:45 +02:00
|
|
|
osg::Vec3f interpolateMovements(const MWPhysics::PtrHolder& ptr, float timeAccum, float physicsDt)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2021-03-21 20:45:46 +00:00
|
|
|
const float interpolationFactor = std::clamp(timeAccum / physicsDt, 0.0f, 1.0f);
|
2021-10-09 18:15:45 +02:00
|
|
|
return ptr.getPosition() * interpolationFactor + ptr.getPreviousPosition() * (1.f - interpolationFactor);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2022-01-29 05:04:32 +01:00
|
|
|
using LockedActorSimulation
|
|
|
|
= std::pair<std::shared_ptr<MWPhysics::Actor>, std::reference_wrapper<MWPhysics::ActorFrameData>>;
|
|
|
|
using LockedProjectileSimulation
|
|
|
|
= std::pair<std::shared_ptr<MWPhysics::Projectile>, std::reference_wrapper<MWPhysics::ProjectileFrameData>>;
|
|
|
|
|
2021-10-07 21:47:05 +02:00
|
|
|
namespace Visitors
|
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
template <class Impl, template <class> class Lock>
|
|
|
|
struct WithLockedPtr
|
|
|
|
{
|
|
|
|
const Impl& mImpl;
|
|
|
|
std::shared_mutex& mCollisionWorldMutex;
|
2023-02-12 14:51:46 +01:00
|
|
|
const MWPhysics::LockingPolicy mLockingPolicy;
|
2022-01-29 05:04:32 +01:00
|
|
|
|
|
|
|
template <class Ptr, class FrameData>
|
|
|
|
void operator()(MWPhysics::SimulationImpl<Ptr, FrameData>& sim) const
|
|
|
|
{
|
|
|
|
auto locked = sim.lock();
|
|
|
|
if (!locked.has_value())
|
|
|
|
return;
|
|
|
|
auto&& [ptr, frameData] = *std::move(locked);
|
|
|
|
// Locked shared_ptr has to be destructed after releasing mCollisionWorldMutex to avoid
|
|
|
|
// possible deadlock. Ptr destructor also acquires mCollisionWorldMutex.
|
|
|
|
const std::pair arg(std::move(ptr), frameData);
|
2023-02-12 14:51:46 +01:00
|
|
|
const Lock<std::shared_mutex> lock(mCollisionWorldMutex, mLockingPolicy);
|
2022-01-29 05:04:32 +01:00
|
|
|
mImpl(arg);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-10-07 21:47:05 +02:00
|
|
|
struct InitPosition
|
|
|
|
{
|
|
|
|
const btCollisionWorld* mCollisionWorld;
|
|
|
|
void operator()(MWPhysics::ActorSimulation& sim) const
|
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
auto locked = sim.lock();
|
|
|
|
if (!locked.has_value())
|
2022-01-21 00:28:56 +00:00
|
|
|
return;
|
2022-01-29 05:04:32 +01:00
|
|
|
auto& [actor, frameDataRef] = *locked;
|
|
|
|
auto& frameData = frameDataRef.get();
|
2021-10-07 21:47:05 +02:00
|
|
|
actor->applyOffsetChange();
|
|
|
|
frameData.mPosition = actor->getPosition();
|
|
|
|
if (frameData.mWaterCollision && frameData.mPosition.z() < frameData.mWaterlevel
|
|
|
|
&& actor->canMoveToWaterSurface(frameData.mWaterlevel, mCollisionWorld))
|
|
|
|
{
|
2021-11-01 12:44:36 +01:00
|
|
|
const auto offset = osg::Vec3f(0, 0, frameData.mWaterlevel - frameData.mPosition.z());
|
|
|
|
MWBase::Environment::get().getWorld()->moveObjectBy(actor->getPtr(), offset);
|
|
|
|
actor->applyOffsetChange();
|
|
|
|
frameData.mPosition = actor->getPosition();
|
2021-10-07 21:47:05 +02:00
|
|
|
}
|
|
|
|
frameData.mOldHeight = frameData.mPosition.z();
|
|
|
|
const auto rotation = actor->getPtr().getRefData().getPosition().asRotationVec3();
|
|
|
|
frameData.mRotation = osg::Vec2f(rotation.x(), rotation.z());
|
|
|
|
frameData.mInertia = actor->getInertialForce();
|
|
|
|
frameData.mStuckFrames = actor->getStuckFrames();
|
|
|
|
frameData.mLastStuckPosition = actor->getLastStuckPosition();
|
|
|
|
}
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(MWPhysics::ProjectileSimulation& /*sim*/) const {}
|
2021-10-07 21:47:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct PreStep
|
|
|
|
{
|
|
|
|
btCollisionWorld* mCollisionWorld;
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(const LockedActorSimulation& sim) const
|
2021-10-07 21:47:05 +02:00
|
|
|
{
|
|
|
|
MWPhysics::MovementSolver::unstuck(sim.second, mCollisionWorld);
|
|
|
|
}
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(const LockedProjectileSimulation& /*sim*/) const {}
|
2021-10-07 21:47:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct UpdatePosition
|
|
|
|
{
|
|
|
|
btCollisionWorld* mCollisionWorld;
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(const LockedActorSimulation& sim) const
|
2021-10-07 21:47:05 +02:00
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
auto& [actor, frameDataRef] = sim;
|
|
|
|
auto& frameData = frameDataRef.get();
|
2021-10-07 21:47:05 +02:00
|
|
|
if (actor->setPosition(frameData.mPosition))
|
|
|
|
{
|
|
|
|
frameData.mPosition = actor->getPosition(); // account for potential position change made by script
|
|
|
|
actor->updateCollisionObjectPosition();
|
|
|
|
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(const LockedProjectileSimulation& sim) const
|
2021-10-09 18:16:29 +02:00
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
auto& [proj, frameDataRef] = sim;
|
|
|
|
auto& frameData = frameDataRef.get();
|
2021-10-09 18:16:29 +02:00
|
|
|
proj->setPosition(frameData.mPosition);
|
|
|
|
proj->updateCollisionObjectPosition();
|
|
|
|
mCollisionWorld->updateSingleAabb(proj->getCollisionObject());
|
|
|
|
}
|
2021-10-07 21:47:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Move
|
|
|
|
{
|
|
|
|
const float mPhysicsDt;
|
|
|
|
const btCollisionWorld* mCollisionWorld;
|
|
|
|
const MWPhysics::WorldFrameData& mWorldFrameData;
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(const LockedActorSimulation& sim) const
|
2021-10-07 21:47:05 +02:00
|
|
|
{
|
|
|
|
MWPhysics::MovementSolver::move(sim.second, mPhysicsDt, mCollisionWorld, mWorldFrameData);
|
|
|
|
}
|
2022-01-29 05:04:32 +01:00
|
|
|
void operator()(const LockedProjectileSimulation& sim) const
|
2021-10-09 18:16:29 +02:00
|
|
|
{
|
2021-12-29 15:11:48 +01:00
|
|
|
if (sim.first->isActive())
|
|
|
|
MWPhysics::MovementSolver::move(sim.second, mPhysicsDt, mCollisionWorld);
|
2021-10-09 18:16:29 +02:00
|
|
|
}
|
2021-10-07 21:47:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Sync
|
|
|
|
{
|
|
|
|
const bool mAdvanceSimulation;
|
|
|
|
const float mTimeAccum;
|
|
|
|
const float mPhysicsDt;
|
|
|
|
const MWPhysics::PhysicsTaskScheduler* scheduler;
|
|
|
|
void operator()(MWPhysics::ActorSimulation& sim) const
|
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
auto locked = sim.lock();
|
|
|
|
if (!locked.has_value())
|
2022-01-21 00:28:56 +00:00
|
|
|
return;
|
2022-01-29 05:04:32 +01:00
|
|
|
auto& [actor, frameDataRef] = *locked;
|
|
|
|
auto& frameData = frameDataRef.get();
|
2021-10-07 21:47:05 +02:00
|
|
|
auto ptr = actor->getPtr();
|
|
|
|
|
|
|
|
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
|
|
|
const float heightDiff = frameData.mPosition.z() - frameData.mOldHeight;
|
|
|
|
const bool isStillOnGround = (mAdvanceSimulation && frameData.mWasOnGround && frameData.mIsOnGround);
|
|
|
|
|
|
|
|
if (isStillOnGround || frameData.mFlying || isUnderWater(frameData) || frameData.mSlowFall < 1)
|
|
|
|
stats.land(ptr == MWMechanics::getPlayer() && (frameData.mFlying || isUnderWater(frameData)));
|
|
|
|
else if (heightDiff < 0)
|
|
|
|
stats.addToFallHeight(-heightDiff);
|
|
|
|
|
2021-10-09 18:15:45 +02:00
|
|
|
actor->setSimulationPosition(::interpolateMovements(*actor, mTimeAccum, mPhysicsDt));
|
2021-10-07 21:47:05 +02:00
|
|
|
actor->setLastStuckPosition(frameData.mLastStuckPosition);
|
|
|
|
actor->setStuckFrames(frameData.mStuckFrames);
|
|
|
|
if (mAdvanceSimulation)
|
|
|
|
{
|
|
|
|
MWWorld::Ptr standingOn;
|
|
|
|
auto* ptrHolder
|
|
|
|
= static_cast<MWPhysics::PtrHolder*>(scheduler->getUserPointer(frameData.mStandingOn));
|
|
|
|
if (ptrHolder)
|
|
|
|
standingOn = ptrHolder->getPtr();
|
|
|
|
actor->setStandingOnPtr(standingOn);
|
|
|
|
// the "on ground" state of an actor might have been updated by a traceDown, don't overwrite the
|
|
|
|
// change
|
|
|
|
if (actor->getOnGround() == frameData.mWasOnGround)
|
|
|
|
actor->setOnGround(frameData.mIsOnGround);
|
|
|
|
actor->setOnSlope(frameData.mIsOnSlope);
|
|
|
|
actor->setWalkingOnWater(frameData.mWalkingOnWater);
|
|
|
|
actor->setInertialForce(frameData.mInertia);
|
|
|
|
}
|
2021-10-09 18:16:29 +02:00
|
|
|
}
|
|
|
|
void operator()(MWPhysics::ProjectileSimulation& sim) const
|
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
auto locked = sim.lock();
|
|
|
|
if (!locked.has_value())
|
2022-01-21 00:28:56 +00:00
|
|
|
return;
|
2022-01-29 05:04:32 +01:00
|
|
|
auto& [proj, frameData] = *locked;
|
2021-10-09 18:16:29 +02:00
|
|
|
proj->setSimulationPosition(::interpolateMovements(*proj, mTimeAccum, mPhysicsDt));
|
2021-10-07 21:47:05 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2023-02-12 14:51:46 +01:00
|
|
|
}
|
2021-10-07 21:47:05 +02:00
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
namespace MWPhysics
|
|
|
|
{
|
|
|
|
namespace
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
int getMaxBulletSupportedThreads()
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2020-10-19 21:26:21 +02:00
|
|
|
auto broad = std::make_unique<btDbvtBroadphase>();
|
2023-02-12 14:51:46 +01:00
|
|
|
return broad->m_rayTestStacks.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
LockingPolicy detectLockingPolicy()
|
|
|
|
{
|
|
|
|
if (Settings::Manager::getInt("async num threads", "Physics") < 1)
|
|
|
|
return LockingPolicy::NoLocks;
|
|
|
|
if (getMaxBulletSupportedThreads() > 1)
|
|
|
|
return LockingPolicy::AllowSharedLocks;
|
|
|
|
Log(Debug::Warning) << "Bullet was not compiled with multithreading support, 1 async thread will be used";
|
|
|
|
return LockingPolicy::ExclusiveLocksOnly;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getNumThreads(LockingPolicy lockingPolicy)
|
|
|
|
{
|
|
|
|
switch (lockingPolicy)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
case LockingPolicy::NoLocks:
|
|
|
|
return 0;
|
|
|
|
case LockingPolicy::ExclusiveLocksOnly:
|
|
|
|
return 1;
|
|
|
|
case LockingPolicy::AllowSharedLocks:
|
|
|
|
return static_cast<unsigned>(std::max(
|
|
|
|
getMaxBulletSupportedThreads(), Settings::Manager::getInt("async num threads", "Physics")));
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
2023-02-12 14:51:46 +01:00
|
|
|
|
|
|
|
throw std::runtime_error("Unsupported LockingPolicy: "
|
|
|
|
+ std::to_string(static_cast<std::underlying_type_t<LockingPolicy>>(lockingPolicy)));
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace MWPhysics
|
|
|
|
{
|
2021-03-26 23:45:56 +01:00
|
|
|
PhysicsTaskScheduler::PhysicsTaskScheduler(
|
|
|
|
float physicsDt, btCollisionWorld* collisionWorld, MWRender::DebugDrawer* debugDrawer)
|
2021-03-21 20:45:46 +00:00
|
|
|
: mDefaultPhysicsDt(physicsDt)
|
|
|
|
, mPhysicsDt(physicsDt)
|
2020-10-28 18:02:31 +04:00
|
|
|
, mTimeAccum(0.f)
|
2021-03-26 23:43:49 +01:00
|
|
|
, mCollisionWorld(collisionWorld)
|
2021-03-26 23:45:56 +01:00
|
|
|
, mDebugDrawer(debugDrawer)
|
2023-02-12 14:51:46 +01:00
|
|
|
, mLockingPolicy(detectLockingPolicy())
|
|
|
|
, mNumThreads(getNumThreads(mLockingPolicy))
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
, mNumJobs(0)
|
|
|
|
, mRemainingSteps(0)
|
|
|
|
, mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics"))
|
2021-11-24 19:10:02 +01:00
|
|
|
, mFrameCounter(0)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
, mAdvanceSimulation(false)
|
|
|
|
, mQuit(false)
|
|
|
|
, mNextJob(0)
|
|
|
|
, mNextLOS(0)
|
2020-11-20 13:11:53 +01:00
|
|
|
, mFrameNumber(0)
|
|
|
|
, mTimer(osg::Timer::instance())
|
2021-03-21 20:45:46 +00:00
|
|
|
, mPrevStepCount(1)
|
|
|
|
, mBudget(physicsDt)
|
|
|
|
, mAsyncBudget(0.0f)
|
|
|
|
, mBudgetCursor(0)
|
|
|
|
, mAsyncStartTime(0)
|
2021-01-09 14:21:57 +04:00
|
|
|
, mTimeBegin(0)
|
|
|
|
, mTimeEnd(0)
|
|
|
|
, mFrameStart(0)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
|
|
|
if (mNumThreads >= 1)
|
|
|
|
{
|
2022-07-12 14:58:25 +02:00
|
|
|
for (unsigned i = 0; i < mNumThreads; ++i)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mThreads.emplace_back([&] { worker(); });
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-24 12:40:47 +02:00
|
|
|
mLOSCacheExpiry = 0;
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2021-05-05 23:25:13 +02:00
|
|
|
mPreStepBarrier = std::make_unique<Misc::Barrier>(mNumThreads);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2021-05-05 23:25:13 +02:00
|
|
|
mPostStepBarrier = std::make_unique<Misc::Barrier>(mNumThreads);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2021-05-05 23:25:13 +02:00
|
|
|
mPostSimBarrier = std::make_unique<Misc::Barrier>(mNumThreads);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PhysicsTaskScheduler::~PhysicsTaskScheduler()
|
|
|
|
{
|
2021-11-24 19:10:02 +01:00
|
|
|
waitForWorkers();
|
2021-10-05 15:43:21 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mSimulationMutex, mLockingPolicy);
|
2021-10-05 15:43:21 +02:00
|
|
|
mQuit = true;
|
|
|
|
mNumJobs = 0;
|
|
|
|
mRemainingSteps = 0;
|
2021-11-24 19:10:02 +01:00
|
|
|
mHasJob.notify_all();
|
2021-10-05 15:43:21 +02:00
|
|
|
}
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
for (auto& thread : mThreads)
|
|
|
|
thread.join();
|
|
|
|
}
|
|
|
|
|
2021-03-21 20:45:46 +00:00
|
|
|
std::tuple<int, float> PhysicsTaskScheduler::calculateStepConfig(float timeAccum) const
|
|
|
|
{
|
|
|
|
int maxAllowedSteps = 2;
|
|
|
|
int numSteps = timeAccum / mDefaultPhysicsDt;
|
|
|
|
|
|
|
|
// adjust maximum step count based on whether we're likely physics bottlenecked or not
|
|
|
|
// if maxAllowedSteps ends up higher than numSteps, we will not invoke delta time
|
|
|
|
// if it ends up lower than numSteps, but greater than 1, we will run a number of true delta time physics steps
|
|
|
|
// that we expect to be within budget if it ends up lower than numSteps and also 1, we will run a single delta
|
|
|
|
// time physics step if we did not do this, and had a fixed step count limit, we would have an unnecessarily low
|
|
|
|
// render framerate if we were only physics bottlenecked, and we would be unnecessarily invoking true delta time
|
|
|
|
// if we were only render bottlenecked
|
|
|
|
|
|
|
|
// get physics timing stats
|
|
|
|
float budgetMeasurement = std::max(mBudget.get(), mAsyncBudget.get());
|
|
|
|
// time spent per step in terms of the intended physics framerate
|
|
|
|
budgetMeasurement /= mDefaultPhysicsDt;
|
|
|
|
// ensure sane minimum value
|
|
|
|
budgetMeasurement = std::max(0.00001f, budgetMeasurement);
|
|
|
|
// we're spending almost or more than realtime per physics frame; limit to a single step
|
|
|
|
if (budgetMeasurement > 0.95)
|
|
|
|
maxAllowedSteps = 1;
|
|
|
|
// physics is fairly cheap; limit based on expense
|
|
|
|
if (budgetMeasurement < 0.5)
|
|
|
|
maxAllowedSteps = std::ceil(1.0 / budgetMeasurement);
|
|
|
|
// limit to a reasonable amount
|
|
|
|
maxAllowedSteps = std::min(10, maxAllowedSteps);
|
|
|
|
|
|
|
|
// fall back to delta time for this frame if fixed timestep physics would fall behind
|
|
|
|
float actualDelta = mDefaultPhysicsDt;
|
|
|
|
if (numSteps > maxAllowedSteps)
|
|
|
|
{
|
|
|
|
numSteps = maxAllowedSteps;
|
|
|
|
// ensure that we do not simulate a frame ahead when doing delta time; this reduces stutter and latency
|
|
|
|
// this causes interpolation to 100% use the most recent physics result when true delta time is happening
|
|
|
|
// and we deliberately simulate up to exactly the timestamp that we want to render
|
|
|
|
actualDelta = timeAccum / float(numSteps + 1);
|
|
|
|
// actually: if this results in a per-step delta less than the target physics steptime, clamp it
|
|
|
|
// this might reintroduce some stutter, but only comes into play in obscure cases
|
|
|
|
// (because numSteps is originally based on mDefaultPhysicsDt, this won't cause us to overrun)
|
|
|
|
actualDelta = std::max(actualDelta, mDefaultPhysicsDt);
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_tuple(numSteps, actualDelta);
|
|
|
|
}
|
|
|
|
|
2022-09-07 01:55:51 +02:00
|
|
|
void PhysicsTaskScheduler::applyQueuedMovements(float& timeAccum, std::vector<Simulation>& simulations,
|
|
|
|
osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2022-09-07 01:55:51 +02:00
|
|
|
assert(mSimulations != &simulations);
|
|
|
|
|
2021-11-24 19:10:02 +01:00
|
|
|
waitForWorkers();
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
// This function run in the main thread.
|
|
|
|
// While the mSimulationMutex is held, background physics threads can't run.
|
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mSimulationMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2021-03-21 20:45:46 +00:00
|
|
|
double timeStart = mTimer->tick();
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
// start by finishing previous background computation
|
|
|
|
if (mNumThreads != 0)
|
|
|
|
{
|
2021-09-29 10:17:31 +02:00
|
|
|
syncWithMainThread();
|
2021-09-25 16:06:30 +02:00
|
|
|
|
2021-03-21 20:45:46 +00:00
|
|
|
if (mAdvanceSimulation)
|
|
|
|
mAsyncBudget.update(mTimer->delta_s(mAsyncStartTime, mTimeEnd), mPrevStepCount, mBudgetCursor);
|
2020-12-18 21:18:04 +01:00
|
|
|
updateStats(frameStart, frameNumber, stats);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2021-03-21 20:45:46 +00:00
|
|
|
auto [numSteps, newDelta] = calculateStepConfig(timeAccum);
|
|
|
|
timeAccum -= numSteps * newDelta;
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
// init
|
2021-10-07 21:47:05 +02:00
|
|
|
const Visitors::InitPosition vis{ mCollisionWorld };
|
|
|
|
for (auto& sim : simulations)
|
2021-07-22 19:29:20 +02:00
|
|
|
{
|
2021-10-07 21:47:05 +02:00
|
|
|
std::visit(vis, sim);
|
2021-07-22 19:29:20 +02:00
|
|
|
}
|
2021-03-21 20:45:46 +00:00
|
|
|
mPrevStepCount = numSteps;
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mRemainingSteps = numSteps;
|
|
|
|
mTimeAccum = timeAccum;
|
2021-03-21 20:45:46 +00:00
|
|
|
mPhysicsDt = newDelta;
|
2022-09-07 01:55:51 +02:00
|
|
|
mSimulations = &simulations;
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mAdvanceSimulation = (mRemainingSteps != 0);
|
2021-11-24 19:10:02 +01:00
|
|
|
++mFrameCounter;
|
2022-09-07 01:55:51 +02:00
|
|
|
mNumJobs = mSimulations->size();
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mNextLOS.store(0, std::memory_order_relaxed);
|
|
|
|
mNextJob.store(0, std::memory_order_release);
|
|
|
|
|
|
|
|
if (mAdvanceSimulation)
|
|
|
|
mWorldFrameData = std::make_unique<WorldFrameData>();
|
|
|
|
|
2021-03-21 20:45:46 +00:00
|
|
|
if (mAdvanceSimulation)
|
|
|
|
mBudgetCursor += 1;
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
if (mNumThreads == 0)
|
|
|
|
{
|
2021-09-29 10:17:31 +02:00
|
|
|
doSimulation();
|
|
|
|
syncWithMainThread();
|
2021-03-21 20:45:46 +00:00
|
|
|
if (mAdvanceSimulation)
|
|
|
|
mBudget.update(mTimer->delta_s(timeStart, mTimer->tick()), numSteps, mBudgetCursor);
|
2021-07-31 23:26:10 +02:00
|
|
|
return;
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2021-03-21 20:45:46 +00:00
|
|
|
mAsyncStartTime = mTimer->tick();
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mHasJob.notify_all();
|
2021-03-21 20:45:46 +00:00
|
|
|
if (mAdvanceSimulation)
|
|
|
|
mBudget.update(mTimer->delta_s(timeStart, mTimer->tick()), 1, mBudgetCursor);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2021-07-31 23:26:10 +02:00
|
|
|
void PhysicsTaskScheduler::resetSimulation(const ActorMap& actors)
|
2020-12-03 12:57:57 +01:00
|
|
|
{
|
2021-11-24 19:10:02 +01:00
|
|
|
waitForWorkers();
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mSimulationMutex, mLockingPolicy);
|
2021-03-21 20:45:46 +00:00
|
|
|
mBudget.reset(mDefaultPhysicsDt);
|
|
|
|
mAsyncBudget.reset(0.0f);
|
2022-09-07 01:55:51 +02:00
|
|
|
if (mSimulations != nullptr)
|
|
|
|
{
|
|
|
|
mSimulations->clear();
|
|
|
|
mSimulations = nullptr;
|
|
|
|
}
|
2020-12-05 01:09:43 +01:00
|
|
|
for (const auto& [_, actor] : actors)
|
|
|
|
{
|
2020-12-19 20:25:46 +01:00
|
|
|
actor->updatePosition();
|
2020-12-18 09:22:02 +01:00
|
|
|
actor->updateCollisionObjectPosition();
|
2020-12-05 01:09:43 +01:00
|
|
|
}
|
2020-12-03 12:57:57 +01:00
|
|
|
}
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld,
|
|
|
|
btCollisionWorld::RayResultCallback& resultCallback) const
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mCollisionWorld->rayTest(rayFromWorld, rayToWorld, resultCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::convexSweepTest(const btConvexShape* castShape, const btTransform& from,
|
|
|
|
const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mCollisionWorld->convexSweepTest(castShape, from, to, resultCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::contactTest(
|
|
|
|
btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback)
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeSharedLock lock(mCollisionWorldMutex, mLockingPolicy);
|
2021-03-26 23:43:49 +01:00
|
|
|
ContactTestWrapper::contactTest(mCollisionWorld, colObj, resultCallback);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2020-10-21 11:08:59 +02:00
|
|
|
std::optional<btVector3> PhysicsTaskScheduler::getHitPoint(const btTransform& from, btCollisionObject* target)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
// target the collision object's world origin, this should be the center of the collision object
|
|
|
|
btTransform rayTo;
|
|
|
|
rayTo.setIdentity();
|
|
|
|
rayTo.setOrigin(target->getWorldTransform().getOrigin());
|
|
|
|
|
|
|
|
btCollisionWorld::ClosestRayResultCallback cb(from.getOrigin(), rayTo.getOrigin());
|
|
|
|
|
|
|
|
mCollisionWorld->rayTestSingle(
|
|
|
|
from, rayTo, target, target->getCollisionShape(), target->getWorldTransform(), cb);
|
|
|
|
if (!cb.hasHit())
|
|
|
|
// didn't hit the target. this could happen if point is already inside the collision box
|
2020-10-21 11:08:59 +02:00
|
|
|
return std::nullopt;
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
return { cb.m_hitPointWorld };
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::aabbTest(
|
|
|
|
const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeSharedLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mCollisionWorld->getBroadphase()->aabbTest(aabbMin, aabbMax, callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max)
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeSharedLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
obj->getCollisionShape()->getAabb(obj->getWorldTransform(), min, max);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask)
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
collisionObject->getBroadphaseHandle()->m_collisionFilterMask = collisionFilterMask;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::addCollisionObject(
|
|
|
|
btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
|
|
|
|
{
|
2021-07-23 22:37:55 +02:00
|
|
|
mCollisionObjects.insert(collisionObject);
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mCollisionWorld->addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::removeCollisionObject(btCollisionObject* collisionObject)
|
|
|
|
{
|
2021-07-23 22:37:55 +02:00
|
|
|
mCollisionObjects.erase(collisionObject);
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mCollisionWorld->removeCollisionObject(collisionObject);
|
|
|
|
}
|
|
|
|
|
2022-01-22 17:17:20 +01:00
|
|
|
void PhysicsTaskScheduler::updateSingleAabb(const std::shared_ptr<PtrHolder>& ptr, bool immediate)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2021-07-25 18:00:48 +02:00
|
|
|
if (immediate || mNumThreads == 0)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2020-12-18 09:22:02 +01:00
|
|
|
updatePtrAabb(ptr);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mUpdateAabbMutex, mLockingPolicy);
|
2022-01-22 17:17:20 +01:00
|
|
|
mUpdateAabb.insert(ptr);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-14 23:15:11 +02:00
|
|
|
bool PhysicsTaskScheduler::getLineOfSight(
|
|
|
|
const std::shared_ptr<Actor>& actor1, const std::shared_ptr<Actor>& actor2)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mLOSCacheMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
|
|
|
auto req = LOSRequest(actor1, actor2);
|
|
|
|
auto result = std::find(mLOSCache.begin(), mLOSCache.end(), req);
|
|
|
|
if (result == mLOSCache.end())
|
|
|
|
{
|
2021-08-14 23:15:11 +02:00
|
|
|
req.mResult = hasLineOfSight(actor1.get(), actor2.get());
|
2021-04-24 12:40:47 +02:00
|
|
|
mLOSCache.push_back(req);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
return req.mResult;
|
|
|
|
}
|
|
|
|
result->mAge = 0;
|
|
|
|
return result->mResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::refreshLOSCache()
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeSharedLock lock(mLOSCacheMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
int job = 0;
|
|
|
|
int numLOS = mLOSCache.size();
|
|
|
|
while ((job = mNextLOS.fetch_add(1, std::memory_order_relaxed)) < numLOS)
|
|
|
|
{
|
|
|
|
auto& req = mLOSCache[job];
|
|
|
|
auto actorPtr1 = req.mActors[0].lock();
|
|
|
|
auto actorPtr2 = req.mActors[1].lock();
|
|
|
|
|
|
|
|
if (req.mAge++ > mLOSCacheExpiry || !actorPtr1 || !actorPtr2)
|
|
|
|
req.mStale = true;
|
|
|
|
else
|
|
|
|
req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::updateAabbs()
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mUpdateAabbMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
std::for_each(mUpdateAabb.begin(), mUpdateAabb.end(), [this](const std::weak_ptr<PtrHolder>& ptr) {
|
2022-01-22 17:17:20 +01:00
|
|
|
auto p = ptr.lock();
|
|
|
|
if (p != nullptr)
|
|
|
|
updatePtrAabb(p);
|
|
|
|
});
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mUpdateAabb.clear();
|
|
|
|
}
|
|
|
|
|
2021-08-14 23:15:11 +02:00
|
|
|
void PhysicsTaskScheduler::updatePtrAabb(const std::shared_ptr<PtrHolder>& ptr)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mCollisionWorldMutex, mLockingPolicy);
|
2021-08-14 23:15:11 +02:00
|
|
|
if (const auto actor = std::dynamic_pointer_cast<Actor>(ptr))
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2021-08-14 23:15:11 +02:00
|
|
|
actor->updateCollisionObjectPosition();
|
|
|
|
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
|
|
|
}
|
|
|
|
else if (const auto object = std::dynamic_pointer_cast<Object>(ptr))
|
|
|
|
{
|
|
|
|
object->commitPositionChange();
|
|
|
|
mCollisionWorld->updateSingleAabb(object->getCollisionObject());
|
|
|
|
}
|
|
|
|
else if (const auto projectile = std::dynamic_pointer_cast<Projectile>(ptr))
|
|
|
|
{
|
2021-10-09 18:13:54 +02:00
|
|
|
projectile->updateCollisionObjectPosition();
|
2021-08-14 23:15:11 +02:00
|
|
|
mCollisionWorld->updateSingleAabb(projectile->getCollisionObject());
|
|
|
|
}
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::worker()
|
|
|
|
{
|
2021-11-24 19:10:02 +01:00
|
|
|
std::size_t lastFrame = 0;
|
2020-10-21 11:08:59 +02:00
|
|
|
std::shared_lock lock(mSimulationMutex);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
while (!mQuit)
|
|
|
|
{
|
2021-11-24 19:10:02 +01:00
|
|
|
if (lastFrame == mFrameCounter)
|
|
|
|
{
|
|
|
|
mHasJob.wait(lock, [&] { return mQuit || lastFrame != mFrameCounter; });
|
|
|
|
lastFrame = mFrameCounter;
|
|
|
|
}
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2021-09-29 10:17:31 +02:00
|
|
|
doSimulation();
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::updateActorsPositions()
|
|
|
|
{
|
2022-01-29 05:04:32 +01:00
|
|
|
const Visitors::UpdatePosition impl{ mCollisionWorld };
|
|
|
|
const Visitors::WithLockedPtr<Visitors::UpdatePosition, MaybeExclusiveLock> vis{ impl, mCollisionWorldMutex,
|
2023-02-12 14:51:46 +01:00
|
|
|
mLockingPolicy };
|
2022-09-07 01:55:51 +02:00
|
|
|
for (Simulation& sim : *mSimulations)
|
2021-10-07 21:47:05 +02:00
|
|
|
std::visit(vis, sim);
|
2021-07-23 22:37:55 +02:00
|
|
|
}
|
|
|
|
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2)
|
|
|
|
{
|
|
|
|
btVector3 pos1 = Misc::Convert::toBullet(
|
|
|
|
actor1->getCollisionObjectPosition() + osg::Vec3f(0, 0, actor1->getHalfExtents().z() * 0.9)); // eye level
|
|
|
|
btVector3 pos2 = Misc::Convert::toBullet(
|
|
|
|
actor2->getCollisionObjectPosition() + osg::Vec3f(0, 0, actor2->getHalfExtents().z() * 0.9));
|
|
|
|
|
|
|
|
btCollisionWorld::ClosestRayResultCallback resultCallback(pos1, pos2);
|
2021-04-11 10:28:56 +02:00
|
|
|
resultCallback.m_collisionFilterGroup = CollisionType_AnyPhysical;
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_HeightMap | CollisionType_Door;
|
|
|
|
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeLock lockColWorld(mCollisionWorldMutex, mLockingPolicy);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
mCollisionWorld->rayTest(pos1, pos2, resultCallback);
|
|
|
|
|
|
|
|
return !resultCallback.hasHit();
|
|
|
|
}
|
|
|
|
|
2021-09-29 10:17:31 +02:00
|
|
|
void PhysicsTaskScheduler::doSimulation()
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2021-09-29 10:17:31 +02:00
|
|
|
while (mRemainingSteps)
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
{
|
2021-09-29 10:17:31 +02:00
|
|
|
mPreStepBarrier->wait([this] { afterPreStep(); });
|
|
|
|
int job = 0;
|
2022-01-29 05:04:32 +01:00
|
|
|
const Visitors::Move impl{ mPhysicsDt, mCollisionWorld, *mWorldFrameData };
|
2023-02-12 14:51:46 +01:00
|
|
|
const Visitors::WithLockedPtr<Visitors::Move, MaybeLock> vis{ impl, mCollisionWorldMutex, mLockingPolicy };
|
2021-09-29 10:17:31 +02:00
|
|
|
while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
2022-09-07 01:55:51 +02:00
|
|
|
std::visit(vis, (*mSimulations)[job]);
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
|
2021-09-29 10:17:31 +02:00
|
|
|
mPostStepBarrier->wait([this] { afterPostStep(); });
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
|
|
|
|
2021-07-30 22:23:42 +02:00
|
|
|
refreshLOSCache();
|
2021-09-29 10:17:31 +02:00
|
|
|
mPostSimBarrier->wait([this] { afterPostSim(); });
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|
2020-12-18 21:18:04 +01:00
|
|
|
|
|
|
|
void PhysicsTaskScheduler::updateStats(osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
|
|
|
{
|
2021-01-27 08:04:33 +00:00
|
|
|
if (!stats.collectStats("engine"))
|
|
|
|
return;
|
2020-12-18 21:18:04 +01:00
|
|
|
if (mFrameNumber == frameNumber - 1)
|
|
|
|
{
|
|
|
|
stats.setAttribute(mFrameNumber, "physicsworker_time_begin", mTimer->delta_s(mFrameStart, mTimeBegin));
|
|
|
|
stats.setAttribute(mFrameNumber, "physicsworker_time_taken", mTimer->delta_s(mTimeBegin, mTimeEnd));
|
|
|
|
stats.setAttribute(mFrameNumber, "physicsworker_time_end", mTimer->delta_s(mFrameStart, mTimeEnd));
|
|
|
|
}
|
|
|
|
mFrameStart = frameStart;
|
|
|
|
mTimeBegin = mTimer->tick();
|
|
|
|
mFrameNumber = frameNumber;
|
|
|
|
}
|
2021-03-26 23:45:56 +01:00
|
|
|
|
|
|
|
void PhysicsTaskScheduler::debugDraw()
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeSharedLock lock(mCollisionWorldMutex, mLockingPolicy);
|
2021-03-26 23:45:56 +01:00
|
|
|
mDebugDrawer->step();
|
|
|
|
}
|
2021-05-05 23:25:13 +02:00
|
|
|
|
2021-07-23 22:37:55 +02:00
|
|
|
void* PhysicsTaskScheduler::getUserPointer(const btCollisionObject* object) const
|
|
|
|
{
|
|
|
|
auto it = mCollisionObjects.find(object);
|
|
|
|
if (it == mCollisionObjects.end())
|
|
|
|
return nullptr;
|
|
|
|
return (*it)->getUserPointer();
|
|
|
|
}
|
|
|
|
|
2021-08-14 23:15:11 +02:00
|
|
|
void PhysicsTaskScheduler::releaseSharedStates()
|
|
|
|
{
|
2021-11-24 19:10:02 +01:00
|
|
|
waitForWorkers();
|
2021-08-14 23:15:11 +02:00
|
|
|
std::scoped_lock lock(mSimulationMutex, mUpdateAabbMutex);
|
2022-09-07 01:55:51 +02:00
|
|
|
if (mSimulations != nullptr)
|
|
|
|
{
|
|
|
|
mSimulations->clear();
|
|
|
|
mSimulations = nullptr;
|
|
|
|
}
|
2021-08-14 23:15:11 +02:00
|
|
|
mUpdateAabb.clear();
|
|
|
|
}
|
|
|
|
|
2021-05-05 23:25:13 +02:00
|
|
|
void PhysicsTaskScheduler::afterPreStep()
|
|
|
|
{
|
2021-04-24 12:40:47 +02:00
|
|
|
updateAabbs();
|
2021-05-05 23:25:13 +02:00
|
|
|
if (!mRemainingSteps)
|
|
|
|
return;
|
2022-01-29 05:04:32 +01:00
|
|
|
const Visitors::PreStep impl{ mCollisionWorld };
|
|
|
|
const Visitors::WithLockedPtr<Visitors::PreStep, MaybeExclusiveLock> vis{ impl, mCollisionWorldMutex,
|
2023-02-12 14:51:46 +01:00
|
|
|
mLockingPolicy };
|
2022-09-07 01:55:51 +02:00
|
|
|
for (auto& sim : *mSimulations)
|
2021-10-07 21:47:05 +02:00
|
|
|
std::visit(vis, sim);
|
2021-05-05 23:25:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::afterPostStep()
|
|
|
|
{
|
|
|
|
if (mRemainingSteps)
|
|
|
|
{
|
|
|
|
--mRemainingSteps;
|
|
|
|
updateActorsPositions();
|
|
|
|
}
|
|
|
|
mNextJob.store(0, std::memory_order_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PhysicsTaskScheduler::afterPostSim()
|
|
|
|
{
|
|
|
|
{
|
2023-02-12 14:51:46 +01:00
|
|
|
MaybeExclusiveLock lock(mLOSCacheMutex, mLockingPolicy);
|
2021-05-05 23:25:13 +02:00
|
|
|
mLOSCache.erase(
|
|
|
|
std::remove_if(mLOSCache.begin(), mLOSCache.end(), [](const LOSRequest& req) { return req.mStale; }),
|
|
|
|
mLOSCache.end());
|
|
|
|
}
|
|
|
|
mTimeEnd = mTimer->tick();
|
2021-11-24 19:10:02 +01:00
|
|
|
|
|
|
|
std::unique_lock lock(mWorkersDoneMutex);
|
|
|
|
++mWorkersFrameCounter;
|
|
|
|
mWorkersDone.notify_all();
|
2021-05-05 23:25:13 +02:00
|
|
|
}
|
2021-09-29 10:17:31 +02:00
|
|
|
|
|
|
|
void PhysicsTaskScheduler::syncWithMainThread()
|
|
|
|
{
|
2022-09-07 01:55:51 +02:00
|
|
|
if (mSimulations == nullptr)
|
|
|
|
return;
|
2021-10-07 21:47:05 +02:00
|
|
|
const Visitors::Sync vis{ mAdvanceSimulation, mTimeAccum, mPhysicsDt, this };
|
2022-09-07 01:55:51 +02:00
|
|
|
for (auto& sim : *mSimulations)
|
2021-10-07 21:47:05 +02:00
|
|
|
std::visit(vis, sim);
|
2022-09-07 01:55:51 +02:00
|
|
|
mSimulations->clear();
|
|
|
|
mSimulations = nullptr;
|
2021-09-29 10:17:31 +02:00
|
|
|
}
|
2021-11-24 19:10:02 +01:00
|
|
|
|
|
|
|
// Attempt to acquire unique lock on mSimulationMutex while not all worker
|
|
|
|
// threads are holding shared lock but will have to may lead to a deadlock because
|
|
|
|
// C++ standard does not guarantee priority for exclusive and shared locks
|
|
|
|
// for std::shared_mutex. For example microsoft STL implementation points out
|
|
|
|
// for the absence of such priority:
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/sync/slim-reader-writer--srw--locks
|
|
|
|
void PhysicsTaskScheduler::waitForWorkers()
|
|
|
|
{
|
|
|
|
if (mNumThreads == 0)
|
|
|
|
return;
|
|
|
|
std::unique_lock lock(mWorkersDoneMutex);
|
|
|
|
if (mFrameCounter != mWorkersFrameCounter)
|
|
|
|
mWorkersDone.wait(lock);
|
|
|
|
}
|
Process movement queue in one or several background threads
Before movement calculation, the main thread prepare a
vector of ActorFrameData, which contains all data necessary to perform
the simulation, and feed it to the solver. At the same time it fetches
the result from the previous background simulation, which in turn is
used by the game mechanics.
Other functions of the physics system (weapon hit for instance)
interrupt the background simulation, with some exceptions described
below.
The number of threads is controlled by the numeric setting
[Physics]
async num threads
In case 'async num threads' > 1 and Bullet doesn't support multiple threads,
1 async thread will be used. 0 means synchronous solver.
Additional settings (will be silently switched off if async num threads = 0)
[Physics]
defer aabb update
Update AABBs of actors and objects in the background thread(s). It is not an especially
costly operation, but it needs exclusive access to the collision world, which blocks
other operations. Since AABB needs to be updated for collision detection, one can queue
them to defer update before start of the movement solver. Extensive tests on as much
as one installation (mine) show no drawback having that switched on.
[Physics]
lineofsight keep inactive cache
Control for how long (how many frames) the line of sight (LOS) request will be kept updated.
When a request for LOS is made for the first time, the background threads are stopped to
service it. From now on, the LOS will be refreshed preemptively as part of the background
routine until it is not required for lineofsight keep inactive cache frames. This mean
that subsequent request will not interrupt the background computation.
2020-10-15 06:11:44 +02:00
|
|
|
}
|