SL-1481 Don't predict region crossings over a second

meow-7.2.2
andreykproductengine 2018-12-04 17:52:46 +02:00
parent 3eff729828
commit 4c92c7b2d0
4 changed files with 59 additions and 16 deletions

View File

@ -14068,6 +14068,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>RegionCrossingInterpolationTime</key>
<map>
<key>Comment</key>
<string>How long to extrapolate object motion after crossing regions</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>VerboseLogs</key>
<map>
<key>Comment</key>

View File

@ -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;
}

View File

@ -615,7 +615,7 @@ private:
U32 checkMediaURL(const std::string &media_url);
// Motion prediction between updates
void interpolateLinearMotion(const F64SecondsImplicit & time, const F32SecondsImplicit & dt);
void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt);
static void initObjectDataMap();
@ -851,6 +851,7 @@ protected:
static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; }
static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; }
static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; }
static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; }
static void setPingInterpolate(BOOL value) { sPingInterpolate = value; }
@ -860,6 +861,7 @@ private:
static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation
static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation
static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation
static BOOL sVelocityInterpolate;
static BOOL sPingInterpolate;

View File

@ -854,6 +854,7 @@ void LLViewerObjectList::update(LLAgent &agent)
F32 interp_time = gSavedSettings.getF32("InterpolationTime");
F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut");
F32 region_interp_time = llclamp(gSavedSettings.getF32("RegionCrossingInterpolationTime"), 0.5f, 5.f);
if (interp_time < 0.0 ||
phase_out_time < 0.0 ||
phase_out_time > interp_time)
@ -864,6 +865,7 @@ void LLViewerObjectList::update(LLAgent &agent)
}
LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time );
LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time );
LLViewerObject::setMaxRegionCrossingInterpolationTime(region_interp_time);
gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");