Use faster aabbTest but without destance filter. To avoid dependency on a
specific constant and correctly handle situations when there is a big
difference between actors sizes.
Simple Physics API modification for Lua
See merge request OpenMW/openmw!1216
(cherry picked from commit d88494c90b501d0832ae0330a0ca81d8b8e5aa50)
02dd055a Save hitObject in castSphere() just like in castRay()
0793d0bf Allow to override collision mask and group for castSphere() as for castRay()
- enchanted arrow explode upon hit the water plane
- non enchanted arrow disappear (or more accurately, they hit nothingness)
- enchanted arrow shot underwater explode immediately
- non enchanted arrow disappear immediately
Also, solve a bug that occured previously and could theoritically still happens where we use the last tested collision position for instead of the last registered hit:
Use the hit position as saved inside Projectile::hit() instead of the last position saved inside the callback.
If a projectile collides with several objects (bottom of the sea and water surface for instance), the last collision tested won't necessarily be the impact position as we have no control over the order in which the tests are performed.
simulation
The purpose of weak_ptr is to avoid performing the simulation on deleted
Actor by promoting it to a shared_ptr via a lock() call. This clutter
the code with a lot of branches, whereas the overwhelmingly common case is for the call to succeed.
Since the simulation is decoupled from the engine state, we can use a shared_ptr instead of a weak_ptr.
This allow us to ignore (ie not handle) the rarer case where the actor is delete from the scene. This means that the simulation
will run for one frame more than before for each actor, whereas the rest of the engine
will be ignorant of this.
MWWorld::Ptr:
- they are equivalent
- btCollisionObject* is readily available from the simulation, it saves
a call to a mutex
- btCollisionObject* is smaller
- 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
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)
- 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)
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.
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
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.
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.
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
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"
be sure the simulation is over. Otherwise, if the simulation is too slow
the position is wrong, and the actors would jump back and forth between
old and new position instead of actually moving.
Before this change, if an actor position was changed while the physics
simulation was running, the simulation result would be discarded. It is
fine in case of one off event such as teleport, but in the case of
scripts making use of this functionality to make lifts or conveyor (such
as Sotha Sil Expanded mod) it broke actor movement.
To alleviate this issue, at the end of the simulation, the position of the Actor
in the world is compared to the position it had at the beginning of the
simulation. A difference indicate a force move occured. In this case,
the Actor mPosition and mPreviousPosition are translated by the difference of position.
Since the Actor position will be really set while the next simulation runs, we
save it in the mNextPosition field.
it is updated in the solver only if the actor is standing on
"something". The ground is not "something", so in case the actor goes
from standing on an object to the standing on the ground, this change was not taken
into account.
Clear the value before the simulation to solve this problem.