MAINT-646: Optimize LLVolumeImplFlexible::doIdleUpdate() https://bitbucket.org/davep/viewer-development/changeset/b0148737d316

This commit is contained in:
Shyotl
2012-07-20 08:54:25 -05:00
parent 1a3c9ac5ef
commit 6331267df6
3 changed files with 71 additions and 68 deletions

View File

@@ -255,50 +255,28 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons
{ {
} }
//---------------------------------------------------------------------------------
// This calculates the physics of the flexible object. Note that it has to be 0 void LLVolumeImplFlexible::updateRenderRes()
// 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)
{ {
if (mVO->mDrawable.isNull()) LLDrawable* drawablep = mVO->mDrawable;
{
// Don't do anything until we have a drawable
return FALSE; // (we are not initialized or updated)
}
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(); S32 new_res = mAttributes->getSimulateLOD();
//number of segments only cares about z axis #if 1 //optimal approximation of previous behavior that doesn't rely on atan2
F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera;
// Rendering sections increases with visible angle on the screen // 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()); mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS) #endif
{
mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS; mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS);
}
// Bottom cap at 1/4 the original number of sections
if (mRenderRes < mAttributes->getSimulateLOD()-1)
{
mRenderRes = mAttributes->getSimulateLOD()-1;
}
// Throttle back simulation of segments we're not rendering // Throttle back simulation of segments we're not rendering
if (mRenderRes < new_res) if (mRenderRes < new_res)
{ {
@@ -311,43 +289,65 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
setAttributesOfAllSections(); setAttributesOfAllSections();
mInitialized = TRUE; mInitialized = TRUE;
} }
if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) }
{ //---------------------------------------------------------------------------------
return FALSE; // (we are not initialized or updated) // 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;
bool visible = mVO->mDrawable->isVisible(); if (drawablep)
if (force_update && visible)
{ {
gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
}
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; LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
} parent->mDrawable->mQuietCount = 0;
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 (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
{ {
gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); bool visible = drawablep->isVisible();
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) inline S32 log2(S32 x)
@@ -369,7 +369,9 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
{ {
//mVO->markForUpdate(TRUE); //mVO->markForUpdate(TRUE);
if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0);
if (mSimulateRes == 0)
{ {
return; // we did not get updated or initialized, proceeding without can be dangerous return; // we did not get updated or initialized, proceeding without can be dangerous
} }

View File

@@ -84,7 +84,8 @@ class LLVolumeImplFlexible : public LLVolumeInterface
LLVector3 getFramePosition() const; LLVector3 getFramePosition() const;
LLQuaternion getFrameRotation() const; LLQuaternion getFrameRotation() const;
LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; } 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); BOOL doUpdateGeometry(LLDrawable *drawable);
LLVector3 getPivotPosition() const; LLVector3 getPivotPosition() const;
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);

View File

@@ -70,7 +70,7 @@ class LLVolumeInterface
public: public:
virtual ~LLVolumeInterface() { } virtual ~LLVolumeInterface() { }
virtual LLVolumeInterfaceType getInterfaceType() const = 0; 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 BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
virtual LLVector3 getPivotPosition() const = 0; virtual LLVector3 getPivotPosition() const = 0;
virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;