1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-05 06:40:09 +00:00

243 Commits

Author SHA1 Message Date
fredzio
0c5cf6ec19 Store the btCollisionObject* of the object we're standing on instead of
MWWorld::Ptr:
- they are equivalent
- btCollisionObject* is readily available from the simulation, it saves
  a call to a mutex
- btCollisionObject* is smaller
2021-08-07 13:38:24 +02:00
fredzio
26d9052b8c Move the weak_ptr<Actor> outside of ActorFrameData. 2021-08-07 13:38:24 +02:00
fredzio
f68273c3c0 Remove Actor* from ActorFrameData 2021-08-07 13:38:24 +02:00
fredzio
b04c958410 Modify the way swimming is handled:
- compute the swimming state instead of storing it, it changes as part of the simulation and was not updated, so it was wrong anyway.
- store the swim level in ActorFrameData, it is constant per Actor so no need to compute it inside the simulation
2021-08-07 13:38:24 +02:00
fredzio
51514e44cc Handle jump as part of the simulation preparation (inside of
PhysicsSystem) instead of inside the simulaiton.
For mechanics, we don't care how the jump is handled, just that it will be.
2021-08-07 13:38:24 +02:00
fredzio
1bfaf353be Explicitely store all the potential states an Actor can have into the
ActActorFrameData structure. It makes it easier to reason about the
simulation (and hopefully simplify it).
Remove atomics from Actor class as a side effect.

Rename mFloatToSurface to mInert to make is explicit what it represent, not what it is used for
Store the Actor rotation (1 Vec2) instead of the whole ESM::Position (2 Vec3)
2021-08-07 13:38:24 +02:00
fredzio
9472728fa4 Do not generate data for immobile actors instead of early out from the solver 2021-08-07 13:38:24 +02:00
fredzio
bc738c5640 Use extract/insert instead of erase/emplace
When we call moveObject(), we might trigger a change of cell for the
actor, which in turn triggers updatePtr(). The erase/emplace
construct invalidate references, whereas extract/insert do not.

The reason is was working before !1075 is because we were always
"refreshing" the reference by a call to getActor().
2021-08-03 07:00:42 +02:00
psi29a
547bc4a252 Merge branch 'notonlyactors' into 'master'
Refactor the physics simulation to make it not actor centric.

See merge request OpenMW/openmw!1075
2021-07-31 23:39:22 +00:00
fredzio
35928cf4d3 Refactor a bit the physics simulation to make it not actor centric:
- inline PhysicsSystem::applyQueuedMovements() into PhysicsSystem::stepSimulation()
- rename PhysicsTaskScheduler::moveActors() to PhysicsTaskScheduler::applyQueuedMovements()
- move the actor movement code from World::doPhysics() to
  PhysicsSystem::moveActors() (analogically to the projectile manager)
2021-07-31 23:39:04 +02:00
fredzio
c76387162b Add projectiles number to the resources stats 2021-07-31 23:08:50 +02:00
fredzio
88a5ca440b Change moveObject() to take a osg::Vec3f argument instead of 3 floats
for readability.
2021-07-30 23:24:49 +02:00
fredzio
f348b70733 Set mCanWaterWalk and mOnGround when adding Actor to the scene.
mCanWaterWalk was set to false and updated during next frame's simulation
mOnGround is set to true but then was updated as part of the scene
loading logic.
2021-07-23 18:04:58 +02:00
fredzio
f02d01ef0c Do not store btTransform into Object class: reduce its size by 104 bytes 2021-07-17 13:11:41 +02:00
Evil Eye
0a15d7740a Delay physics for objects created by scripts 2021-07-05 18:34:06 +02:00
Evil Eye
4f264af5a9 Merge branch 'staticsload' into 'master'
Loads statics before actors II (#5379)

See merge request OpenMW/openmw!588
2021-06-28 20:25:51 +00:00
fredzio
c795e0bce6 Some actors are supposed to spawn on an object that belongs to an adjacent cell.
Since actors can be active in 3x3 grid around the player, we need to
first load all objects in a 5x5 grid around the player.

Split load and unloading in 2 phases. Add an mInactiveCells set into the
scene, which contains all cells inside the aforementioned 5x5 grid.
These cells contains only heightfields and non-animated physics objects.

Animated objects are tied to the scene graph, which doesn't exists yet
in these cells, so we skip them.
2021-06-28 09:36:04 +02:00
jvoisin
1123dc46ee Add a ton of const refs 2021-06-23 23:13:59 +02:00
Evil Eye
b8472e1303 Use modified paralyze magnitude to fall and float 2021-05-28 16:55:54 +02:00
fredzio
b13afd758c Remove both racy and useless code.
Actor's position can be determined in 3 ways:
1/ as a result of physics simulation
2/ after a script require a relative position change (SetPos, Move)
3/ absolutely set from games mechanics event (teleport) or script
(PositionCell)

In case 1/, RefData::mPosition is updated with the physics simulation result
In case 2/, when RefData::mPosition is updated, physics simulation is informed of the change and update accordingly
In case 3/, when RefData::mPosition is updated, the physics simulation state is reset

In all 3 cases, we don't need to check the RefData::mPosition to get a
correct behaviour.

TSAN reported the following data race:
  Read of size 4 at 0x7b50005b75b0 by thread T12 (mutexes: write M656173, write M84859534346343880):
    #0 ESM::Position::asVec3() const /build/openmw/openmw/master2/.build/freebsd/TSAN/../../.././components/esm/defs.hpp:55:27 (openmw+0xb809d5)
    #1 MWPhysics::Actor::updateWorldPosition() /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/actor.cpp:131:59 (openmw+0xb809d5)
    #2 MWPhysics::Actor::setPosition(osg::Vec3f const&) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/actor.cpp:177:5 (openmw+0xb809d5)
    #3 MWPhysics::PhysicsTaskScheduler::updateActorsPositions() /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/mtphysics.cpp:524:28 (openmw+0xb91ac0)
    #4 MWPhysics::PhysicsTaskScheduler::afterPostStep() /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/mtphysics.cpp:614:13 (openmw+0xb915e7)
    #5 MWPhysics::PhysicsTaskScheduler::worker()::$_5::operator()() const /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/mtphysics.cpp:498:45 (openmw+0xb915e7)
    #6 void Misc::Barrier::wait<MWPhysics::PhysicsTaskScheduler::worker()::$_5>(MWPhysics::PhysicsTaskScheduler::worker()::$_5&&) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../.././components/misc/barrier.hpp:30:21 (openmw+0xb915e7)
    #7 MWPhysics::PhysicsTaskScheduler::worker() /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/mtphysics.cpp:498:31 (openmw+0xb915e7)
    #8 MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0::operator()() const /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwphysics/mtphysics.cpp:162:45 (openmw+0xb92630)
    #9 decltype(std::__1::forward<MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0>(fp)()) std::__1::__invoke<MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0>(MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0&&) /usr/include/c++/v1/type_traits:3899:1 (openmw+0xb92630)
    #10 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0>&, std::__1::__tuple_indices<>) /usr/include/c++/v1/thread:280:5 (openmw+0xb92630)
    #11 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, MWPhysics::PhysicsTaskScheduler::PhysicsTaskScheduler(float, btCollisionWorld*, MWRender::DebugDrawer*)::$_0> >(void*) /usr/include/c++/v1/thread:291:5 (openmw+0xb92630)

  Previous write of size 8 at 0x7b50005b75b0 by main thread:
    #0 memcpy /wrkdirs/usr/ports/devel/llvm-devel/work-default/llvm-project-3f6753efe1990a928ed120bd907940a9fb3e2fc3/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:827:5 (openmw+0x55a057)
    #1 MWWorld::RefData::setPosition(ESM::Position const&) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwworld/refdata.cpp:216:19 (openmw+0xa3de1c)
    #2 MWWorld::World::moveObject(MWWorld::Ptr const&, MWWorld::CellStore*, float, float, float, bool) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwworld/worldimp.cpp:1130:26 (openmw+0xa57300)
    #3 MWWorld::World::moveObject(MWWorld::Ptr const&, float, float, float, bool, bool) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwworld/worldimp.cpp:1253:16 (openmw+0xa580c8)
    #4 MWWorld::World::doPhysics(float, unsigned long long, unsigned int, osg::Stats&) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwworld/worldimp.cpp:1530:17 (openmw+0xa5af8f)
    #5 MWWorld::World::updatePhysics(float, bool, unsigned long long, unsigned int, osg::Stats&) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/mwworld/worldimp.cpp:1862:13 (openmw+0xa61a7c)
    #6 OMW::Engine::frame(float) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/engine.cpp:333:42 (openmw+0xcce9e7)
    #7 OMW::Engine::go() /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/engine.cpp:935:14 (openmw+0xcd86ed)
    #8 runApplication(int, char**) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/main.cpp:296:17 (openmw+0xcbffac)
    #9 wrapApplication(int (*)(int, char**), int, char**, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../components/debug/debugging.cpp:205:15 (openmw+0x1335442)
    #10 main /build/openmw/openmw/master2/.build/freebsd/TSAN/../../../apps/openmw/main.cpp:308:12 (openmw+0xcc008a)
:wqa
2021-05-20 20:46:44 +02:00
fredzio
5b63019719 Embed actor velocity inside its class. It makes the code simpler. 2021-05-16 12:42:17 +02:00
psi29a
9b017ef04d Merge branch 'internal_includes_openmw' into 'master'
Clean up some internal includes of the openmw component

See merge request OpenMW/openmw!796
2021-05-07 10:53:25 +00:00
Andrei Kortunov
a0582caa26 Fix uninitialized variable 2021-05-07 10:41:14 +04:00
fredzio
4fa0972b2d Tone down actor's skip simulation flag to an optional skip collision
detection flag.
2021-05-01 14:22:30 +02:00
jvoisin
be371ccd9f An another pass 2021-04-30 20:27:33 +02:00
fredzio
9d8fcec642 Remove bogus warning. It is a normal situation for projectiles to be
in-flight after the caster is gone.
2021-04-14 09:01:37 +02:00
fredzio
6e1c67a9ae Account for waterwalking when updating position. Otherwise we might
trace down the actor at waterlevel at the wrong coordinate.

Triggered by multimark mod with waterwalking effect.
2021-04-09 23:33:21 +02:00
fredzio
b58244ac26 Guard the Bullet drawing method with a read lock on the
btCollisionWorld. It closes a race on the collision shapes coordinates.
2021-03-26 23:49:31 +01:00
fredzio
dbd6e3bfee Replace pointless usage of shared_ptr by unique_ptr / non-owning raw
pointer for btCollisionWorld.
2021-03-26 23:49:31 +01:00
wareya
63f01d8c5f Prevent physics death spiral by falling back to true delta time when needed 2021-03-21 20:45:46 +00:00
fredzio
03b86c232b Apply the position offset even if the simulation is not performed
because we're too fast.
2021-03-13 09:52:05 +01:00
Alexei Dobrohotov
2bfee281fd Merge branch 'restore_caster' into 'master'
Restore projectile caster from savegame (#5860)

See merge request OpenMW/openmw!616

(cherry picked from commit d595c7adb0fb45eafed6d3d0403ad640a91411ed)

c5426bec In the savegame, projectile caster is identified by its actor id. When
2021-03-05 21:07:29 +00:00
psi29a
59e09cba5b Merge branch 'boltsize' into 'master'
Use projectile mesh size (#5829)

See merge request OpenMW/openmw!587
2021-02-15 08:40:30 +00:00
fredzio
6e969ca3fa Use mesh collision box instead of node bounding sphere for projectile
size. The bounding sphere is much bigger than the mesh.
2021-02-05 22:53:45 +01:00
Andrei Kortunov
7b727e4d70 Revert "Remove physics dependency on basenode"
This reverts commit 165c7314928dc281a364fa1a0143c45fd6d2adfd.
2021-01-29 16:51:13 +04:00
Andrei Kortunov
165af1c365 Revert "Some actors are supposed to spawn on a static object that belong to an adjacent cell."
This reverts commit f031a191b847443c848637b17d0936a43b5070b5.
2021-01-29 16:51:05 +04:00
fredzio
f031a191b8 Some actors are supposed to spawn on a static object that belong to an adjacent cell.
Since actors can be active in 3x3 grid around the player, we need to
first load all statics in a 5x5 grid around the player.

Split load and unloading in 2 phases. Add an mInactiveCells set into the
scene, which contains all cells inside the aforementioned 5x5 grid.
These cells contains only heightfields and physics objects of static
class.
2021-01-24 14:11:10 +01:00
fredzio
165c731492 Remove physics dependency on basenode
Necessary to be able to load physics objects from inactive cells.
2021-01-24 14:10:27 +01:00
fredzio
1f4c85520f Use convexSweepTest for projectile movement to solve any
imprecision issue with projectile collision detection.
Simplify the mechanics: manage hits in one spot.
Give magic projectiles a collision shape similar in size to their visible
model.

Rename the 2 convex result callback to clearly state their purpose.
2021-01-21 20:36:33 +01:00
fredzio
d015f17a6c Make all physics object manage their own resources
Use smart pointer for heightfields and their members.
Move collision object addition inside of Object's ctor, as for Actors and HeightFields
2021-01-10 14:56:35 +01:00
fredzio
ebb564ad22 call moveObject() after applying waterwalking
This unbreak abot's boat mods: they're continually teleporting
the boats (who is an actor with waterwalking effect). As such, the
physics simulation was never run and the boat never went to sea level.
2020-12-27 17:31:55 +01:00
Alexei Dobrohotov
22476281da Fix paralyze for swimming actors 2020-12-22 08:03:51 +03:00
fredzio
5bd921fa3a Restore pre-async handling of absolute actors positionning
One of the issue since the introduction of async physics is the quirky
handling of scripted moves. Previous attempt to account for them was
based on detecting changes in actor position while the physics thread is
running. To this end, semantics of Actor::updatePosition() (which is
responsible for set the absolute position of an actor in the world) was
toned down to merely store the desired position, with the physics system
actually responsible for moving the actor. For the cases were complete
override of the physics simulation was needed, I introduced
Actor::resetPosition(), which actually have same semantics as
original updatePosition(). This in turn introduced a loads of new bugs
when the weakened semantics broke key assumptions inside the engine
(spawning, summoning, teleport, etc).
Instead of tracking them down, count on the newly introduced support for
object relative movements in the engine (World::moveObjectBy) to
register relative movements and restore original handling of absolute positionning.

Changes are relatively small:
- move resetPosition() content into updatePosition()
- call updatePosition() everywhere it was called before
- remove all added calls to the now non-existing resetPosition()

tldr; ditch last month worth of bug introduction and eradication and redo
it properly
2020-12-20 19:23:09 +01:00
fredzio
8e084dea2e Don't cache Ptr, it can be updated while the simulation is running. 2020-12-18 22:22:37 +01:00
fredzio
4e7c9b6696 Embed physics simulation results inside of actor class.
This gives finer control over reseting positions (switch off tcl is no
longer glitchy) and solve most of the erroneous usage of stale World::Ptr
indicated by:
"Error in frame: moveTo: object is not in this cell"
2020-12-18 12:54:02 +01:00
fredzio
b39437dfb6 Don't allow projectiles to stand still when they hit an ally.
When an NPC fire a projectile, it should affect only its targeted actor.
To this end, after a hit is detected the target is checked against the
list of AI targets and reactivated if necessary.
Problem occurs when the hit occurs as a result of a friendly actor going
into the projectile (detected in ClosestNotMeConvexResultCallback):
while the projectile is inside the friend's collision box, it is
deactivated, just to be immediately reactivated. Effectively, the
projectile does nothing until the actor moves out.

Add a check inside the ClosestNotMeConvexResultCallback before declaring
a hit.
Since the necessary data is not safely accessible from the async thread,
maintain a copy inside the Projectile class.
2020-12-14 22:23:01 +01:00
Alexei Dobrohotov
15291f15d3 Make actor collision box components a struct 2020-12-11 20:07:59 +03:00
fredzio
4fbe1ed12c Ignore caster collision shape. Sometimes the magic bolt get launched
inside too near its caster.
2020-12-08 09:06:34 +01:00
fredzio
7e85235220 Projectile to projectile collision 2020-12-08 09:06:34 +01:00
fredzio
66fe3b0d38 Modify projectile collision to work with async physics 2020-12-08 09:06:33 +01:00