SL-1481 Don't predict region crossings over a second
parent
3eff729828
commit
4c92c7b2d0
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue