MAINT-794 Move flexi idleUpdate and texture animation to their own update queues.

meow-7.2.2
Dave Parks 2012-06-20 18:29:18 -05:00
parent c030e3a51d
commit 7929db82d1
7 changed files with 269 additions and 187 deletions

View File

@ -44,6 +44,8 @@
#include "llvoavatar.h"
/*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f;
std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList;
std::vector<S32> LLVolumeImplFlexible::sUpdateDelay;
static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild");
static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update");
@ -70,8 +72,45 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
{
mVO->mDrawable->makeActive() ;
}
mInstanceIndex = sInstanceList.size();
sInstanceList.push_back(this);
sUpdateDelay.push_back(0);
}//-----------------------------------------------
LLVolumeImplFlexible::~LLVolumeImplFlexible()
{
S32 end_idx = sInstanceList.size()-1;
if (end_idx != mInstanceIndex)
{
sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx];
}
sInstanceList.pop_back();
sUpdateDelay.pop_back();
}
//static
void LLVolumeImplFlexible::updateClass()
{
std::vector<S32>::iterator delay_iter = sUpdateDelay.begin();
for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
iter != sInstanceList.end();
++iter)
{
--(*delay_iter);
if (*delay_iter <= 0)
{
(*iter)->doIdleUpdate();
}
++delay_iter;
}
}
LLVector3 LLVolumeImplFlexible::getFramePosition() const
{
return mVO->getRenderPosition();
@ -296,7 +335,7 @@ void LLVolumeImplFlexible::updateRenderRes()
// 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)
void LLVolumeImplFlexible::doIdleUpdate()
{
LLDrawable* drawablep = mVO->mDrawable;
@ -316,31 +355,45 @@ void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
updateRenderRes();
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
}
else if (visible &&
!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
mVO->getPixelArea() > 256.f)
else
{
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)
if (visible)
{
updateRenderRes();
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
mVO->getPixelArea() > 256.f)
{
U32 id;
if (mVO->isRootEdit())
{
id = mID;
}
else
{
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
id = parent->getVolumeInterfaceID();
}
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
{
sUpdateDelay[mInstanceIndex] = (S32) update_period-1;
updateRenderRes();
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
}
}
}
else
{
sUpdateDelay[mInstanceIndex] = (S32) update_period;
}
}
}
}
}
@ -364,7 +417,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
{
//mVO->markForUpdate(TRUE);
doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0);
doIdleUpdate();
if (mSimulateRes == 0)
{

View File

@ -70,8 +70,16 @@ struct LLFlexibleObjectSection
//---------------------------------------------------------
class LLVolumeImplFlexible : public LLVolumeInterface
{
private:
static std::vector<LLVolumeImplFlexible*> sInstanceList;
static std::vector<S32> sUpdateDelay;
S32 mInstanceIndex;
public:
static void updateClass();
LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes);
~LLVolumeImplFlexible();
// Implements LLVolumeInterface
U32 getID() const { return mID; }
@ -79,7 +87,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
LLQuaternion getFrameRotation() const;
LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; }
void updateRenderRes();
void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
void doIdleUpdate();
BOOL doUpdateGeometry(LLDrawable *drawable);
LLVector3 getPivotPosition() const;
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);

View File

@ -49,6 +49,8 @@
#include "llstring.h"
#include "llhudnametag.h"
#include "lldrawable.h"
#include "llflexibleobject.h"
#include "llviewertextureanim.h"
#include "xform.h"
#include "llsky.h"
#include "llviewercamera.h"
@ -941,6 +943,8 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
objectp = *active_iter;
if (objectp)
{
llassert(objectp->isActive());
if (idle_count >= idle_list.size())
{
idle_list.push_back( objectp );
@ -979,10 +983,19 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
idle_iter != idle_end; idle_iter++)
{
objectp = *idle_iter;
llassert(objectp->isActive());
objectp->idleUpdate(agent, world, frame_time);
}
//update flexible objects
LLVolumeImplFlexible::updateClass();
//update animated textures
LLViewerTextureAnim::updateClass();
}
fetchObjectCosts();
fetchPhysicsFlags();
@ -1402,8 +1415,9 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
{
mActiveObjects[idx] = mActiveObjects[last_index];
mActiveObjects[idx]->setListIndex(idx);
mActiveObjects.pop_back();
}
mActiveObjects.pop_back();
}
}
@ -1447,6 +1461,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)
objectp->setOnActiveList(FALSE);
}
}
llassert(objectp->isActive() || objectp->getListIndex() == -1);
}
void LLViewerObjectList::updateObjectCost(LLViewerObject* object)

View File

@ -27,21 +27,37 @@
#include "llviewerprecompiledheaders.h"
#include "llviewertextureanim.h"
#include "llvovolume.h"
#include "llmath.h"
#include "llerror.h"
LLViewerTextureAnim::LLViewerTextureAnim() : LLTextureAnim()
std::vector<LLViewerTextureAnim*> LLViewerTextureAnim::sInstanceList;
LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim()
{
mVObj = vobj;
mLastFrame = -1.f; // Force an update initially
mLastTime = 0.f;
mOffS = mOffT = 0;
mScaleS = mScaleT = 1;
mRot = 0;
mInstanceIndex = sInstanceList.size();
sInstanceList.push_back(this);
}
LLViewerTextureAnim::~LLViewerTextureAnim()
{
S32 end_idx = sInstanceList.size()-1;
if (end_idx != mInstanceIndex)
{
sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
}
sInstanceList.pop_back();
}
void LLViewerTextureAnim::reset()
@ -50,6 +66,14 @@ void LLViewerTextureAnim::reset()
mTimer.reset();
}
//static
void LLViewerTextureAnim::updateClass()
{
for (std::vector<LLViewerTextureAnim*>::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter)
{
(*iter)->mVObj->animateTextures();
}
}
S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t,
F32 &scale_s, F32 &scale_t,

View File

@ -30,10 +30,18 @@
#include "lltextureanim.h"
#include "llframetimer.h"
class LLVOVolume;
class LLViewerTextureAnim : public LLTextureAnim
{
private:
static std::vector<LLViewerTextureAnim*> sInstanceList;
S32 mInstanceIndex;
public:
LLViewerTextureAnim();
static void updateClass();
LLViewerTextureAnim(LLVOVolume* vobj);
virtual ~LLViewerTextureAnim();
/*virtual*/ void reset();
@ -51,6 +59,7 @@ public:
F32 mRot;
protected:
LLVOVolume* mVObj;
LLFrameTimer mTimer;
F64 mLastTime;
F32 mLastFrame;

View File

@ -329,7 +329,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
if (!mTextureAnimp)
{
mTextureAnimp = new LLViewerTextureAnim();
mTextureAnimp = new LLViewerTextureAnim(this);
}
else
{
@ -431,7 +431,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
if (!mTextureAnimp)
{
mTextureAnimp = new LLViewerTextureAnim();
mTextureAnimp = new LLViewerTextureAnim(this);
}
else
{
@ -498,170 +498,143 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
void LLVOVolume::animateTextures()
{
F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
if (result)
{
if (!mTexAnimMode)
{
mFaceMappingChanged = TRUE;
gPipeline.markTextured(mDrawable);
}
mTexAnimMode = result | mTextureAnimp->mMode;
S32 start=0, end=mDrawable->getNumFaces()-1;
if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
{
start = end = mTextureAnimp->mFace;
}
for (S32 i = start; i <= end; i++)
{
LLFace* facep = mDrawable->getFace(i);
if (!facep) continue;
if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
const LLTextureEntry* te = facep->getTextureEntry();
if (!te)
{
continue;
}
if (!(result & LLViewerTextureAnim::ROTATE))
{
te->getRotation(&rot);
}
if (!(result & LLViewerTextureAnim::TRANSLATE))
{
te->getOffset(&off_s,&off_t);
}
if (!(result & LLViewerTextureAnim::SCALE))
{
te->getScale(&scale_s, &scale_t);
}
if (!facep->mTextureMatrix)
{
facep->mTextureMatrix = new LLMatrix4();
}
LLMatrix4& tex_mat = *facep->mTextureMatrix;
tex_mat.setIdentity();
LLVector3 trans ;
if(facep->isAtlasInUse())
{
//
//if use atlas for animated texture
//apply the following transform to the animation matrix.
//
F32 tcoord_xoffset = 0.f ;
F32 tcoord_yoffset = 0.f ;
F32 tcoord_xscale = 1.f ;
F32 tcoord_yscale = 1.f ;
if(facep->isAtlasInUse())
{
const LLVector2* tmp = facep->getTexCoordOffset() ;
tcoord_xoffset = tmp->mV[0] ;
tcoord_yoffset = tmp->mV[1] ;
tmp = facep->getTexCoordScale() ;
tcoord_xscale = tmp->mV[0] ;
tcoord_yscale = tmp->mV[1] ;
}
trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f));
}
else //non atlas
{
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
}
LLVector3 scale(scale_s, scale_t, 1.f);
LLQuaternion quat;
quat.setQuat(rot, 0, 0, -1.f);
tex_mat.rotate(quat);
LLMatrix4 mat;
mat.initAll(scale, LLQuaternion(), LLVector3());
tex_mat *= mat;
tex_mat.translate(trans);
}
}
else
{
if (mTexAnimMode && mTextureAnimp->mRate == 0)
{
U8 start, count;
if (mTextureAnimp->mFace == -1)
{
start = 0;
count = getNumTEs();
}
else
{
start = (U8) mTextureAnimp->mFace;
count = 1;
}
for (S32 i = start; i < start + count; i++)
{
if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
{
setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
}
if (mTexAnimMode & LLViewerTextureAnim::SCALE)
{
setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
}
if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
{
setTERotation(i, mTextureAnimp->mRot);
}
}
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
mTexAnimMode = 0;
}
}
}
void LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
if (!mDead)
{
if (!mStatic)
{ //do some velocity interpolation/rotation
LLViewerObject::idleUpdate(agent, world, time);
}
//static LLFastTimer::DeclareTimer ftm("Volume Idle");
//LLFastTimer t(ftm);
F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
if (result)
{
if (!mTexAnimMode)
{
mFaceMappingChanged = TRUE;
gPipeline.markTextured(mDrawable);
}
mTexAnimMode = result | mTextureAnimp->mMode;
S32 start=0, end=mDrawable->getNumFaces()-1;
if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
{
start = end = mTextureAnimp->mFace;
}
///////////////////////
//
// Do texture animation stuff
//
for (S32 i = start; i <= end; i++)
{
LLFace* facep = mDrawable->getFace(i);
if (!facep) continue;
if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
if (mTextureAnimp && gAnimateTextures)
{
animateTextures();
const LLTextureEntry* te = facep->getTextureEntry();
if (!te)
{
continue;
}
if (!(result & LLViewerTextureAnim::ROTATE))
{
te->getRotation(&rot);
}
if (!(result & LLViewerTextureAnim::TRANSLATE))
{
te->getOffset(&off_s,&off_t);
}
if (!(result & LLViewerTextureAnim::SCALE))
{
te->getScale(&scale_s, &scale_t);
}
if (!facep->mTextureMatrix)
{
facep->mTextureMatrix = new LLMatrix4();
}
LLMatrix4& tex_mat = *facep->mTextureMatrix;
tex_mat.setIdentity();
LLVector3 trans ;
if(facep->isAtlasInUse())
{
//
//if use atlas for animated texture
//apply the following transform to the animation matrix.
//
F32 tcoord_xoffset = 0.f ;
F32 tcoord_yoffset = 0.f ;
F32 tcoord_xscale = 1.f ;
F32 tcoord_yscale = 1.f ;
if(facep->isAtlasInUse())
{
const LLVector2* tmp = facep->getTexCoordOffset() ;
tcoord_xoffset = tmp->mV[0] ;
tcoord_yoffset = tmp->mV[1] ;
tmp = facep->getTexCoordScale() ;
tcoord_xscale = tmp->mV[0] ;
tcoord_yscale = tmp->mV[1] ;
}
trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f));
}
else //non atlas
{
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
}
LLVector3 scale(scale_s, scale_t, 1.f);
LLQuaternion quat;
quat.setQuat(rot, 0, 0, -1.f);
tex_mat.rotate(quat);
LLMatrix4 mat;
mat.initAll(scale, LLQuaternion(), LLVector3());
tex_mat *= mat;
tex_mat.translate(trans);
}
}
// Dispatch to implementation
if (mVolumeImpl)
else
{
mVolumeImpl->doIdleUpdate(agent, world, time);
if (mTexAnimMode && mTextureAnimp->mRate == 0)
{
U8 start, count;
if (mTextureAnimp->mFace == -1)
{
start = 0;
count = getNumTEs();
}
else
{
start = (U8) mTextureAnimp->mFace;
count = 1;
}
for (S32 i = start; i < start + count; i++)
{
if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
{
setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
}
if (mTexAnimMode & LLViewerTextureAnim::SCALE)
{
setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
}
if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
{
setTERotation(i, mTextureAnimp->mRot);
}
}
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
mTexAnimMode = 0;
}
}
}
}
@ -904,8 +877,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
BOOL LLVOVolume::isActive() const
{
return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive());// ||
//(mDrawable.notNull() && mDrawable->isActive());
return !mStatic;
}
BOOL LLVOVolume::setMaterial(const U8 material)

View File

@ -68,7 +68,7 @@ class LLVolumeInterface
public:
virtual ~LLVolumeInterface() { }
virtual LLVolumeInterfaceType getInterfaceType() const = 0;
virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;
virtual void doIdleUpdate() = 0;
virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
virtual LLVector3 getPivotPosition() const = 0;
virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
@ -114,8 +114,7 @@ public:
void deleteFaces();
void animateTextures();
/*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
BOOL isVisible() const ;
/*virtual*/ BOOL isActive() const;
/*virtual*/ BOOL isAttachment() const;