davep avatar davep committed c8c9652

reapply b0148737d316: MAINT-646 Optimize LLVolumeImplFlexible::doIdleUpdate()

Comments (0)

Files changed (3)

indra/newview/llflexibleobject.cpp

 	mFrameNum = 0;
 	mCollisionSphereRadius = 0.f;
 	mRenderRes = 1;
-
+	
 	if(mVO->mDrawable.notNull())
 	{
 		mVO->mDrawable->makeActive() ;
 {
 }
 
-//---------------------------------------------------------------------------------
-// This calculates the physics of the flexible object. Note that it has to be 0
-// updated every time step. In the future, perhaps there could be an 
-// optimization similar to what Havok does for objects that are stationary. 
-//---------------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
-BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+
+void LLVolumeImplFlexible::updateRenderRes()
 {
-	if (mVO->mDrawable.isNull())
-	{
-		// Don't do anything until we have a drawable
-		return FALSE; // (we are not initialized or updated)
-	}
+	LLDrawable* drawablep = mVO->mDrawable;
 
-	BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
-
-	//flexible objects never go static
-	mVO->mDrawable->mQuietCount = 0;
-	if (!mVO->mDrawable->isRoot())
-	{
-		LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
-		parent->mDrawable->mQuietCount = 0;
-	}
-
-	LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
-		
 	S32 new_res = mAttributes->getSimulateLOD();
 
-	//number of segments only cares about z axis
-	F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
+#if 1 //optimal approximation of previous behavior that doesn't rely on atan2
+	F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera;
 
 	// Rendering sections increases with visible angle on the screen
+	mRenderRes = (S32) (12.f*app_angle);
+#else //legacy behavior
+	//number of segments only cares about z axis
+	F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
+
+ 	// Rendering sections increases with visible angle on the screen
 	mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
-	if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS)
-	{
-		mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS;
-	}
-
-
-	// Bottom cap at 1/4 the original number of sections
-	if (mRenderRes < mAttributes->getSimulateLOD()-1)
-	{
-		mRenderRes = mAttributes->getSimulateLOD()-1;
-	}
+#endif
+		
+	mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS);
+		
 	// Throttle back simulation of segments we're not rendering
 	if (mRenderRes < new_res)
 	{
 		setAttributesOfAllSections();
 		mInitialized = TRUE;
 	}
-	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
+}
+//---------------------------------------------------------------------------------
+// This calculates the physics of the flexible object. Note that it has to be 0
+// updated every time step. In the future, perhaps there could be an 
+// optimization similar to what Havok does for objects that are stationary. 
+//---------------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
+void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+{
+	LLDrawable* drawablep = mVO->mDrawable;
+
+	if (drawablep)
 	{
-		return FALSE; // (we are not initialized or updated)
-	}
+		//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
 
-	bool visible = mVO->mDrawable->isVisible();
-
-	if (force_update && visible)
-	{
-		gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
-	}
-	else if	(visible &&
-		!mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&
-		mVO->getPixelArea() > 256.f)
-	{
-		U32 id;
-		F32 pixel_area = mVO->getPixelArea();
-
-		if (mVO->isRootEdit())
+		//flexible objects never go static
+		drawablep->mQuietCount = 0;
+		if (!drawablep->isRoot())
 		{
-			id = mID;
-		}
-		else
-		{
-			LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
-			id = parent->getVolumeInterfaceID();
+			LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
+			parent->mDrawable->mQuietCount = 0;
 		}
 
-		U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
+		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
+		{
+			bool visible = drawablep->isVisible();
 
-		if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
-		{
-			gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
+			if ((mSimulateRes == 0) && visible)
+			{
+				updateRenderRes();
+				gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+			}
+			else if	(visible &&
+				!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
+				mVO->getPixelArea() > 256.f)
+			{
+				U32 id;
+				F32 pixel_area = mVO->getPixelArea();
+
+				if (mVO->isRootEdit())
+				{
+					id = mID;
+				}
+				else
+				{
+					LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
+					id = parent->getVolumeInterfaceID();
+				}
+
+				U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
+
+				if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
+				{
+					updateRenderRes();
+					gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+				}
+			}
 		}
 	}
-	
-	return force_update;
 }
 
 inline S32 log2(S32 x)

indra/newview/llflexibleobject.h

 		LLVector3 getFramePosition() const;
 		LLQuaternion getFrameRotation() const;
 		LLVolumeInterfaceType getInterfaceType() const		{ return INTERFACE_FLEXIBLE; }
-		BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+		void updateRenderRes();
+		void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
 		BOOL doUpdateGeometry(LLDrawable *drawable);
 		LLVector3 getPivotPosition() const;
 		void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);
 		LLVector3					mCollisionSpherePosition;
 		F32							mCollisionSphereRadius;
 		U32							mID;
-
+		
 		//--------------------------------------
 		// private methods
 		//--------------------------------------

indra/newview/llvovolume.h

 public:
 	virtual ~LLVolumeInterface() { }
 	virtual LLVolumeInterfaceType getInterfaceType() const = 0;
-	virtual BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;
+	virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;
 	virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
 	virtual LLVector3 getPivotPosition() const = 0;
 	virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.