diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 58 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 4 | ||||
| -rw-r--r-- | indra/newview/llviewerobjectlist.cpp | 2 | 
4 files changed, 59 insertions, 16 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3ad8b6cded..0eef5120eb 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -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> 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;  } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index d6c8b76147..990c392531 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -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; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 2aff71367e..932759c86d 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -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");  | 
