summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerobject.cpp
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2018-12-04 17:52:46 +0200
committerandreykproductengine <andreykproductengine@lindenlab.com>2018-12-04 17:52:46 +0200
commit4c92c7b2d025b7cd85bf176287b86a3990959841 (patch)
tree3e746df8a7cf0e62542884c49c9d06e55ff00587 /indra/newview/llviewerobject.cpp
parent3eff7298286c15ac3d2bac40682ba02d6557d663 (diff)
SL-1481 Don't predict region crossings over a second
Diffstat (limited to 'indra/newview/llviewerobject.cpp')
-rw-r--r--indra/newview/llviewerobject.cpp58
1 files changed, 43 insertions, 15 deletions
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1e46a1cf9e..079a9f0372 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -127,6 +127,7 @@ BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion
F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction
+F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing
std::map<std::string, U32> LLViewerObject::sObjectDataMap;
@@ -2487,7 +2488,7 @@ void LLViewerObject::loadFlags(U32 flags)
return;
}
-void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
+void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time)
{
//static LLTrace::BlockTimerStatHandle ftm("Viewer Object");
//LL_RECORD_BLOCK_TIME(ftm);
@@ -2498,19 +2499,19 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
{
// calculate dt from last update
F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f;
- F32 dt_raw = ((F64Seconds)time - mLastInterpUpdateSecs).value();
+ F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value();
F32 dt = time_dilation * dt_raw;
applyAngularVelocity(dt);
if (isAttachment())
{
- mLastInterpUpdateSecs = (F64Seconds)time;
+ mLastInterpUpdateSecs = (F64Seconds)frame_time;
return;
}
else
{ // Move object based on it's velocity and rotation
- interpolateLinearMotion(time, dt);
+ interpolateLinearMotion(frame_time, dt);
}
}
@@ -2520,7 +2521,7 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
// Move an object due to idle-time viewer side updates by interpolating motion
-void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, const F32SecondsImplicit& dt_seconds)
+void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_time, const F32SecondsImplicit& dt_seconds)
{
// linear motion
// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
@@ -2532,7 +2533,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
// zeroing it out
F32 dt = dt_seconds;
- F64Seconds time_since_last_update = time - mLastMessageUpdateSecs;
+ F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs;
if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f)
{
return;
@@ -2580,7 +2581,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
(time_since_last_packet > sPhaseOutUpdateInterpolationTime))
{
// Start to reduce motion interpolation since we haven't seen a server update in a while
- F64Seconds time_since_last_interpolation = time - mLastInterpUpdateSecs;
+ F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs;
F64 phase_out = 1.0;
if (time_since_last_update > sMaxUpdateInterpolationTime)
{ // Past the time limit, so stop the object
@@ -2636,6 +2637,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
// Check to see if it's going off the region
LLVector3 temp(new_pos);
+ static F64SecondsImplicit region_cross_expire = 0; // frame time we detected region crossing in + wait time
if (temp.clamp(0.f, mRegionp->getWidth()))
{ // Going off this region, so see if we might end up on another region
LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
@@ -2644,21 +2646,47 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
// Clip the positions to known regions
LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
if (clip_pos_global != new_pos_global)
- { // Was clipped, so this means we hit a edge where there is no region to enter
-
- //LL_INFOS() << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global)
- // << " from " << new_pos << LL_ENDL;
- new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+ {
+ // Was clipped, so this means we hit a edge where there is no region to enter
+ LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+ LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to "
+ << clip_pos
+ << " from " << new_pos << LL_ENDL;
+ new_pos = clip_pos;
// Stop motion and get server update for bouncing on the edge
new_v.clear();
setAcceleration(LLVector3::zero);
}
else
- { // Let predicted movement cross into another region
- //LL_INFOS() << "Predicting region crossing to " << new_pos << LL_ENDL;
+ {
+ // Check for how long we are crossing.
+ // Note: theoretically we can find time from velocity, acceleration and
+ // distance from border to new position, but it is not going to work
+ // if 'phase_out' activates
+ if (region_cross_expire == 0)
+ {
+ // Workaround: we can't accurately figure out time when we cross border
+ // so just write down time 'after the fact', it is far from optimal in
+ // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first
+ LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL;
+ region_cross_expire = frame_time + sMaxRegionCrossingInterpolationTime;
+ }
+ else if (frame_time > region_cross_expire)
+ {
+ // Predicting crossing over 1s, stop motion
+ // Stop motion
+ LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL;
+ new_v.clear();
+ setAcceleration(LLVector3::zero);
+ region_cross_expire = 0;
+ }
}
}
+ else
+ {
+ region_cross_expire = 0;
+ }
// Set new position and velocity
setPositionRegion(new_pos);
@@ -2669,7 +2697,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
}
// Update the last time we did anything
- mLastInterpUpdateSecs = time;
+ mLastInterpUpdateSecs = frame_time;
}