diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 22 | ||||
| -rw-r--r-- | indra/newview/llmaniptranslate.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llpanelobject.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llviewermessage.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 217 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 21 | ||||
| -rw-r--r-- | indra/newview/llviewerobjectlist.cpp | 19 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.cpp | 21 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.h | 2 | ||||
| -rw-r--r-- | indra/newview/llworld.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llworld.h | 2 | 
12 files changed, 274 insertions, 43 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ebd93b5987..cc8ad74526 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11388,6 +11388,28 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>InterpolationTime</key> +    <map> +      <key>Comment</key> +      <string>How long to extrapolate object motion after last packet received</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>3.0</integer> +    </map> +    <key>InterpolationPhaseOut</key> +    <map> +      <key>Comment</key> +      <string>Seconds to phase out interpolated motion</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>1.0</integer> +    </map>      <key>VerboseLogs</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 5eb3b789f2..f871df0c36 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -726,7 +726,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)  				LLVector3d new_position_global = selectNode->mSavedPositionGlobal + clamped_relative_move;  				// Don't let object centers go too far underground -				F64 min_height = LLWorld::getInstance()->getMinAllowedZ(object); +				F64 min_height = LLWorld::getInstance()->getMinAllowedZ(object, object->getPositionGlobal());  				if (new_position_global.mdV[VZ] < min_height)  				{  					new_position_global.mdV[VZ] = min_height; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index d756a1b931..a0c320ba19 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -1695,10 +1695,10 @@ void LLPanelObject::sendPosition(BOOL btn_down)  	LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());  	LLViewerRegion* regionp = mObject->getRegion(); -		 +  	// Clamp the Z height  	const F32 height = newpos.mV[VZ]; -	const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject); +	const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());  	const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();  	if (!mObject->isAttachment()) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0ca30d5f3d..7c0fc681a4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3866,6 +3866,7 @@ void process_crossed_region(LLMessageSystem* msg, void**)  		return;  	}  	LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL; +	gAgentAvatarp->resetRegionCrossingTimer();  	U32 sim_ip;  	msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 0e1553c421..1804fac1b3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -103,8 +103,8 @@  //#define DEBUG_UPDATE_TYPE -BOOL gVelocityInterpolate = TRUE; -BOOL gPingInterpolate = TRUE;  +BOOL		LLViewerObject::sVelocityInterpolate = TRUE; +BOOL		LLViewerObject::sPingInterpolate = TRUE;   U32			LLViewerObject::sNumZombieObjects = 0;  S32			LLViewerObject::sNumObjects = 0; @@ -115,6 +115,11 @@ S32			LLViewerObject::sAxisArrowLength(50);  BOOL		LLViewerObject::sPulseEnabled(FALSE);  BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE +// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime +F64			LLViewerObject::sMaxUpdateInterpolationTime = 3.0;		// For motion interpolation: after X seconds with no updates, don't predict object motion +F64			LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0;	// For motion interpolation: after Y seconds with no updates, taper off motion prediction + +  static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");  // static @@ -205,6 +210,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mLastInterpUpdateSecs(0.f),  	mLastMessageUpdateSecs(0.f),  	mLatestRecvPacketID(0), +	mCircuitPacketCount(0),  	mData(NULL),  	mAudioSourcep(NULL),  	mAudioGain(1.f), @@ -1841,7 +1847,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	new_rot.normQuat(); -	if (gPingInterpolate) +	if (sPingInterpolate)  	{   		LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());  		if (cdp) @@ -1862,6 +1868,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	//  	// +	// WTF?   If we're going to skip this message, why are we  +	// doing all the parenting, etc above?  	U32 packet_id = mesgsys->getCurrentRecvPacketID();   	if (packet_id < mLatestRecvPacketID &&   		mLatestRecvPacketID - packet_id < 65536) @@ -1871,6 +1879,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	}  	mLatestRecvPacketID = packet_id; +	mCircuitPacketCount = 0;  	// Set the change flags for scale  	if (new_scale != getScale()) @@ -2002,7 +2011,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  //	U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();  	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds(); -	mLastMessageUpdateSecs = LLFrameTimer::getElapsedSeconds(); +	mLastMessageUpdateSecs = mLastInterpUpdateSecs;  	if (mDrawable.notNull())  	{  		// Don't clear invisibility flag on update if still orphaned! @@ -2029,6 +2038,8 @@ BOOL LLViewerObject::isActive() const  	return TRUE;  } + +  BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  {  	static LLFastTimer::DeclareTimer ftm("Viewer Object"); @@ -2042,7 +2053,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  	// CRO - don't velocity interp linked objects!  	// Leviathan - but DO velocity interp joints -	if (!mStatic && gVelocityInterpolate && !isSelected()) +	if (!mStatic && sVelocityInterpolate && !isSelected())  	{  		// calculate dt from last update  		F32 dt_raw = (F32)(time - mLastInterpUpdateSecs); @@ -2132,33 +2143,8 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  			return TRUE;  		}  		else -		{ -			// linear motion -			// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object -			// updates represents the average velocity of the last timestep, rather than the final velocity. -			// the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically -			//  -			// There is a problem here if dt is negative. . . - -			// *TODO: should also wrap linear accel/velocity in check -			// to see if object is selected, instead of explicitly -			// zeroing it out	 -			LLVector3 accel = getAcceleration(); -			LLVector3 vel 	= getVelocity(); -			 -			if (!(accel.isExactlyZero() && vel.isExactlyZero())) -			{ -				LLVector3 pos 	= (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	 -			 -				// region local   -				setPositionRegion(pos + getPositionRegion()); -				setVelocity(vel + accel*dt);	 -				 -				// for objects that are spinning but not translating, make sure to flag them as having moved -				setChanged(MOVED | SILHOUETTE); -			} -			 -			mLastInterpUpdateSecs = time; +		{	// Move object based on it's velocity and rotation +			interpolateLinearMotion(time, dt);  		}  	} @@ -2174,6 +2160,158 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  } +// Move an object due to idle-time viewer side updates by iterpolating motion +void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt) +{ +	// linear motion +	// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object +	// updates represents the average velocity of the last timestep, rather than the final velocity. +	// the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically +	//  +	// *TODO: should also wrap linear accel/velocity in check +	// to see if object is selected, instead of explicitly +	// zeroing it out	 + +	F64 time_since_last_update = time - mLastMessageUpdateSecs; +	if (time_since_last_update <= 0.0 || dt <= 0.f) +	{ +		return; +	} + +	LLVector3 accel = getAcceleration(); +	LLVector3 vel 	= getVelocity(); +	 +	if (sMaxUpdateInterpolationTime <= 0.0) +	{	// Old code path ... unbounded, simple interpolation +		if (!(accel.isExactlyZero() && vel.isExactlyZero())) +		{ +			LLVector3 pos   = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;   +		 +			// region local   +			setPositionRegion(pos + getPositionRegion()); +			setVelocity(vel + accel*dt);	 +			 +			// for objects that are spinning but not translating, make sure to flag them as having moved +			setChanged(MOVED | SILHOUETTE); +		} +	} +	else if (!accel.isExactlyZero() || !vel.isExactlyZero())		// object is moving +	{	// Object is moving, and hasn't been too long since we got an update from the server +		 +		// Calculate predicted position and velocity +		LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	 +		LLVector3 new_v = accel * dt; + +		if (time_since_last_update > sPhaseOutUpdateInterpolationTime) +		{	// Haven't seen a viewer update in a while, check to see if the ciruit is still active +			if (mRegionp) +			{	// The simulator will NOT send updates if the object continues normally on the path +				// predicted by the velocity and the acceleration (often gravity) sent to the viewer +				// So check to see if the circuit is blocked, which means the sim is likely in a long lag +				LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() ); +				if (cdp) +				{ +					if (!cdp->isAlive() ||		// Circuit is dead or blocked +						 cdp->isBlocked() ||	// or doesn't seem to be getting any packets +						 (mCircuitPacketCount > 0 && mCircuitPacketCount == cdp->getPacketsIn())) +					{ +						// Start to reduce motion interpolation since we haven't seen a server update in a while +						F64 time_since_last_interpolation = time - mLastInterpUpdateSecs; +						F64 phase_out = 1.0; +						if (time_since_last_update > sMaxUpdateInterpolationTime) +						{	// Past the time limit, so stop the object +							phase_out = 0.0; +							//llinfos << "Motion phase out to zero" << llendl; + +							// Kill angular motion as well.  Note - not adding this due to paranoia +							// about stopping rotation for llTargetOmega objects and not having it restart +							// setAngularVelocity(LLVector3::zero); +						} +						else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime) +						{	// Last update was already phased out a bit +							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) /  +										(sMaxUpdateInterpolationTime - time_since_last_interpolation); +							//llinfos << "Continuing motion phase out of " << (F32) phase_out << llendl; +						} +						else +						{	// Phase out from full value +							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) /  +										(sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime); +							//llinfos << "Starting motion phase out of " << (F32) phase_out << llendl; +						} +						phase_out = llclamp(phase_out, 0.0, 1.0); + +						new_pos = new_pos * ((F32) phase_out); +						new_v = new_v * ((F32) phase_out); +					} + +					// Save current circuit packet count to see if it changes  +					mCircuitPacketCount = cdp->getPacketsIn(); +				} +			} +		} + +		new_pos = new_pos + getPositionRegion(); +		new_v = new_v + vel; + + +		// Clamp interpolated position to minimum underground and maximum region height +		LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); +		F32 min_height; +		if (isAvatar()) +		{	// Make a better guess about AVs not going underground +			min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global); +			min_height += (0.5f * getScale().mV[VZ]); +		} +		else +		{	// This will put the object underground, but we can't tell if it will stop  +			// at ground level or not +			min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global); +		} + +		new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]); +		new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]); + +		// Check to see if it's going off the region +		LLVector3 temp(new_pos); +		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()); +			new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);		// Re-fetch in case it got clipped above + +			// 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 +				 +				//llinfos << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global) +				//	<< " from " << new_pos << llendl; +				new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global); +				 +				// 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 +				//llinfos << "Predicting region crossing to " << new_pos << llendl; +			} +		} + +		// Set new position and velocity +		setPositionRegion(new_pos); +		setVelocity(new_v);	 +		 +		// for objects that are spinning but not translating, make sure to flag them as having moved +		setChanged(MOVED | SILHOUETTE); +	}		 + +	// Update the last time we did anything +	mLastInterpUpdateSecs = time; +} + + +  BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)  {  	LLMemType mt(LLMemType::MTYPE_OBJECT); @@ -4962,6 +5100,7 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)  	}  	mLatestRecvPacketID = 0; +	mCircuitPacketCount = 0;  	mRegionp = regionp;  	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) @@ -4974,6 +5113,20 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)  	updateDrawable(FALSE);  } +// virtual +void	LLViewerObject::updateRegion(LLViewerRegion *regionp) +{ +//	if (regionp) +//	{ +//		F64 now = LLFrameTimer::getElapsedSeconds(); +//		llinfos << "Updating to region " << regionp->getName() +//			<< ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0) +//			<< ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0)  +//			<< llendl; +//	} +} + +  bool LLViewerObject::specialHoverCursor() const  {  	return (mFlags & FLAGS_USE_PHYSICS) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index c2475c2709..fe670f8827 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -464,7 +464,7 @@ public:  	bool specialHoverCursor() const;	// does it have a special hover cursor?  	void			setRegion(LLViewerRegion *regionp); -	virtual void	updateRegion(LLViewerRegion *regionp) {} +	virtual void	updateRegion(LLViewerRegion *regionp);  	void updateFlags();  	BOOL setFlags(U32 flag, BOOL state); @@ -510,6 +510,9 @@ private:      // and the update wasn't due to this agent's last action.      U32 checkMediaURL(const std::string &media_url); +	// Motion prediction between updates +	void interpolateLinearMotion(const F64 & time, const F32 & dt); +  public:  	//  	// Viewer-side only types - use the LL_PCODE_APP mask. @@ -612,6 +615,8 @@ protected:  	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation  	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator  	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator +	U32				mCircuitPacketCount;			// Packet tracking for early detection of a stopped simulator circuit +  	// extra data sent from the sim...currently only used for tree species info  	U8* mData; @@ -669,9 +674,21 @@ protected:  	mutable LLVector3		mPositionRegion;  	mutable LLVector3		mPositionAgent; +	static void setPhaseOutUpdateInterpolationTime(F32 value)	{ sPhaseOutUpdateInterpolationTime = (F64) value;	} +	static void setMaxUpdateInterpolationTime(F32 value)		{ sMaxUpdateInterpolationTime = (F64) value;	} + +	static void	setVelocityInterpolate(BOOL value)		{ sVelocityInterpolate = value;	} +	static void	setPingInterpolate(BOOL value)			{ sPingInterpolate = value;	} +  private:	  	static S32 sNumObjects; +	static F64 sPhaseOutUpdateInterpolationTime;	// For motion interpolation +	static F64 sMaxUpdateInterpolationTime;			// For motion interpolation + +	static BOOL sVelocityInterpolate; +	static BOOL sPingInterpolate; +  	//--------------------------------------------------------------------  	// For objects that are attachments  	//-------------------------------------------------------------------- @@ -742,7 +759,5 @@ public:  	virtual void updateDrawable(BOOL force_damped);  }; -extern BOOL gVelocityInterpolate; -extern BOOL gPingInterpolate;  #endif diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index a414e86866..f5a32438cf 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -659,9 +659,24 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)  void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  {  	LLMemType mt(LLMemType::MTYPE_OBJECT); +  	// Update globals -	gVelocityInterpolate = gSavedSettings.getBOOL("VelocityInterpolate"); -	gPingInterpolate = gSavedSettings.getBOOL("PingInterpolate"); +	LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") ); +	LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") ); +	 +	F32 interp_time = gSavedSettings.getF32("InterpolationTime"); +	F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut"); +	if (interp_time < 0.0 ||  +		phase_out_time < 0.0 || +		phase_out_time > interp_time) +	{ +		llwarns << "Invalid values for InterpolationTime or InterpolationPhaseOut, resetting to defaults" << llendl; +		interp_time = 3.0f; +		phase_out_time = 1.0f; +	} +	LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time ); +	LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time ); +  	gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");  	// update global timer diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6f3aba29c6..7ae1f672e8 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7864,6 +7864,7 @@ BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)  //virtual  void LLVOAvatar::updateRegion(LLViewerRegion *regionp)  { +	LLViewerObject::updateRegion(regionp);  }  std::string LLVOAvatar::getFullname() const diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e5cbf65682..0250627d1b 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -806,7 +806,24 @@ void LLVOAvatarSelf::removeMissingBakedTextures()  //virtual  void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  { +	// Save the global position +	LLVector3d global_pos_from_old_region = getPositionGlobal(); + +	// Change the region  	setRegion(regionp); + +	if (regionp) +	{	// Set correct region-relative position from global coordinates +		setPositionGlobal(global_pos_from_old_region); + +		// Diagnostic info +		//LLVector3d pos_from_new_region = getPositionGlobal(); +		//llinfos << "pos_from_old_region is " << global_pos_from_old_region +		//	<< " while pos_from_new_region is " << pos_from_new_region +		//	<< llendl; +	} + +  	if (!regionp || (regionp->getHandle() != mLastRegionHandle))  	{  		if (mLastRegionHandle != 0) @@ -820,6 +837,9 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  			F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);  			max = llmax(delta, max);  			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max); + +			// Diagnostics +			llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl;  		}  		if (regionp)  		{ @@ -827,6 +847,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  		}  	}  	mRegionCrossingTimer.reset(); +	LLViewerObject::updateRegion(regionp);  }  //-------------------------------------------------------------------- diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 23a799ea3a..d13cf5ba38 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -123,6 +123,8 @@ public:  	//--------------------------------------------------------------------  	// Region state  	//-------------------------------------------------------------------- +	void			resetRegionCrossingTimer()	{ mRegionCrossingTimer.reset();	} +  private:  	U64				mLastRegionHandle;  	LLFrameTimer	mRegionCrossingTimer; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8fabaaba80..399442e5c4 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -431,14 +431,15 @@ BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global)  // Allow objects to go up to their radius underground. -F32 LLWorld::getMinAllowedZ(LLViewerObject* object) +F32 LLWorld::getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos)  { -	F32 land_height = resolveLandHeightGlobal(object->getPositionGlobal()); +	F32 land_height = resolveLandHeightGlobal(global_pos);  	F32 radius = 0.5f * object->getScale().length();  	return land_height - radius;  } +  LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global)  {  	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index c60dc8dc29..d8ab4bc508 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -89,7 +89,7 @@ public:  	// Return the lowest allowed Z point to prevent objects from being moved  	// underground. -	F32 getMinAllowedZ(LLViewerObject* object); +	F32 getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos);  	// takes a line segment defined by point_a and point_b, then  	// determines the closest (to point_a) point of intersection that is | 
