Restore physical object moved by 3d animation even the first rewind ticks

This commit is contained in:
Benau
2019-03-04 09:54:22 +08:00
parent 475cfa4cdb
commit 38568484fb
6 changed files with 39 additions and 1 deletions

View File

@@ -29,6 +29,8 @@
#include "physics/physics.hpp"
#include "race/history.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object_manager.hpp"
#include "utils/log.hpp"
#include "utils/profiler.hpp"
@@ -358,6 +360,15 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks,
// Update check line, so the cannon animation can be replayed correctly
CheckManager::get()->resetAfterRewind();
if (exact_rewind_ticks > 0)
{
// Restore all physical objects moved by 3d animation, as it only
// set the motion state of physical bodies, it has 1 frame delay
world->setTicksForRewind(exact_rewind_ticks - 1);
Track::getCurrentTrack()->getTrackObjectManager()->resetAfterRewind();
world->setTicksForRewind(exact_rewind_ticks);
}
// Now go forward through the list of rewind infos till we reach 'now':
while (world->getTicksSinceStart() < now_ticks)
{

View File

@@ -224,9 +224,10 @@ public:
/** Returns the ID of this physical object. */
std::string getID() { return m_id; }
// ------------------------------------------------------------------------
btDefaultMotionState* getMotionState() const { return m_motion_state; }
// ------------------------------------------------------------------------
/** Returns the rigid body of this physical object. */
btRigidBody *getBody () { return m_body; }
btRigidBody* getBody() const { return m_body; }
// ------------------------------------------------------------------------
/** Returns true if this object should trigger a rescue in a kart that
* hits it. */

View File

@@ -552,6 +552,20 @@ void TrackObject::update(float dt)
if (m_animator) m_animator->updateWithWorldTicks(true/*has_physics*/);
} // update
// ----------------------------------------------------------------------------
/** This reset all physical object moved by 3d animation back to current ticks
*/
void TrackObject::resetAfterRewind()
{
if (!m_animator || !m_physical_object)
return;
m_animator->updateWithWorldTicks(true/*has_physics*/);
btTransform new_trans;
m_physical_object->getMotionState()->getWorldTransform(new_trans);
m_physical_object->getBody()->setCenterOfMassTransform(new_trans);
} // resetAfterRewind
// ----------------------------------------------------------------------------
/** Does a raycast against the track object. The object must have a physical
* object.

View File

@@ -119,6 +119,7 @@ public:
virtual ~TrackObject();
virtual void update(float dt);
virtual void updateGraphics(float dt);
virtual void resetAfterRewind();
void move(const core::vector3df& xyz, const core::vector3df& hpr,
const core::vector3df& scale, bool updateRigidBody,
bool isAbsoluteCoord);

View File

@@ -195,6 +195,16 @@ void TrackObjectManager::update(float dt)
}
} // update
// ----------------------------------------------------------------------------
void TrackObjectManager::resetAfterRewind()
{
TrackObject* curr;
for_in (curr, m_all_objects)
{
curr->resetAfterRewind();
}
} // resetAfterRewind
// ----------------------------------------------------------------------------
/** Does a raycast against all driveable objects. This way part of the track
* can be a physical object, and can e.g. be animated. A separate list of all

View File

@@ -61,6 +61,7 @@ public:
TrackObject* parent_library);
void updateGraphics(float dt);
void update(float dt);
void resetAfterRewind();
void handleExplosion(const Vec3 &pos, const PhysicalObject *mp,
bool secondary_hits=true);
bool castRay(const btVector3 &from,