summaryrefslogtreecommitdiff
path: root/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r--indra/newview/llvovolume.cpp1256
1 files changed, 674 insertions, 582 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 080d1f774a..c46ccd8ad5 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -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
{
@@ -499,182 +499,144 @@ 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 (!mDead)
{
- 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++)
+ 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)
{
- LLFace* facep = mDrawable->getFace(i);
- if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
-
- const LLTextureEntry* te = facep->getTextureEntry();
-
- if (!te)
+ if (!mTexAnimMode)
{
- continue;
+ mFaceMappingChanged = TRUE;
+ gPipeline.markTextured(mDrawable);
}
-
- if (!(result & LLViewerTextureAnim::ROTATE))
+ mTexAnimMode = result | mTextureAnimp->mMode;
+
+ S32 start=0, end=mDrawable->getNumFaces()-1;
+ if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
{
- te->getRotation(&rot);
+ start = end = mTextureAnimp->mFace;
}
- if (!(result & LLViewerTextureAnim::TRANSLATE))
- {
- te->getOffset(&off_s,&off_t);
- }
- if (!(result & LLViewerTextureAnim::SCALE))
+
+ for (S32 i = start; i <= end; i++)
{
- te->getScale(&scale_s, &scale_t);
- }
+ LLFace* facep = mDrawable->getFace(i);
+ if (!facep) continue;
+ if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
- if (!facep->mTextureMatrix)
- {
- facep->mTextureMatrix = new LLMatrix4();
- }
+ 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);
+ }
- LLMatrix4& tex_mat = *facep->mTextureMatrix;
- tex_mat.setIdentity();
- LLVector3 trans ;
+ 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] ;
+ //
+ //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));
+ 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));
- }
+ 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);
+ LLVector3 scale(scale_s, scale_t, 1.f);
+ LLQuaternion quat;
+ quat.setQuat(rot, 0, 0, -1.f);
- tex_mat.rotate(quat);
+ tex_mat.rotate(quat);
- LLMatrix4 mat;
- mat.initAll(scale, LLQuaternion(), LLVector3());
- tex_mat *= mat;
+ LLMatrix4 mat;
+ mat.initAll(scale, LLQuaternion(), LLVector3());
+ tex_mat *= mat;
- tex_mat.translate(trans);
+ tex_mat.translate(trans);
+ }
}
- }
- else
- {
- if (mTexAnimMode && mTextureAnimp->mRate == 0)
+ else
{
- U8 start, count;
-
- if (mTextureAnimp->mFace == -1)
+ if (mTexAnimMode && mTextureAnimp->mRate == 0)
{
- start = 0;
- count = getNumTEs();
- }
- else
- {
- start = (U8) mTextureAnimp->mFace;
- count = 1;
- }
+ U8 start, count;
- for (S32 i = start; i < start + count; i++)
- {
- if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
+ if (mTextureAnimp->mFace == -1)
{
- setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
+ start = 0;
+ count = getNumTEs();
}
- if (mTexAnimMode & LLViewerTextureAnim::SCALE)
+ else
{
- setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
+ start = (U8) mTextureAnimp->mFace;
+ count = 1;
}
- if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
+
+ for (S32 i = start; i < start + count; i++)
{
- setTERotation(i, mTextureAnimp->mRot);
+ 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;
- }
- }
-}
-BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
-{
- LLViewerObject::idleUpdate(agent, world, time);
-
- static LLFastTimer::DeclareTimer ftm("Volume");
- LLFastTimer t(ftm);
- if (mDead || mDrawable.isNull())
- {
- return TRUE;
- }
-
- ///////////////////////
- //
- // Do texture animation stuff
- //
-
- if (mTextureAnimp && gAnimateTextures)
- {
- animateTextures();
- }
-
- // Dispatch to implementation
- if (mVolumeImpl)
- {
- mVolumeImpl->doIdleUpdate(agent, world, time);
- }
-
- const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40;
-
- if (mDrawable->isActive())
- {
- if (mDrawable->isRoot() &&
- mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES &&
- (!mDrawable->getParent() || !mDrawable->getParent()->isActive()))
- {
- mDrawable->makeStatic();
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ mTexAnimMode = 0;
+ }
}
}
-
- return TRUE;
}
void LLVOVolume::updateTextures()
@@ -682,7 +644,21 @@ void LLVOVolume::updateTextures()
const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
{
- updateTextureVirtualSize();
+ updateTextureVirtualSize();
+
+ if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
+ { //delete vertex buffer to free up some VRAM
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->destroyGL(true);
+
+ //flag the group as having changed geometry so it gets a rebuild next time
+ //it becomes visible
+ group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+ }
+ }
+
}
}
@@ -715,7 +691,18 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if(!forced)
{
if(!isVisible())
- {
+ { //don't load textures for non-visible faces
+ const S32 num_faces = mDrawable->getNumFaces();
+ for (S32 i = 0; i < num_faces; i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (face)
+ {
+ face->setPixelArea(0.f);
+ face->setVirtualSize(0.f);
+ }
+ }
+
return ;
}
@@ -743,6 +730,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
for (S32 i = 0; i < num_faces; i++)
{
LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
const LLTextureEntry *te = face->getTextureEntry();
LLViewerTexture *imagep = face->getTexture();
if (!imagep || !te ||
@@ -889,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)
@@ -1062,9 +1049,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+ bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
+ (!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
+
+ if (cache_in_vram)
+ { //this volume might be used as source data for a transform object, put it in vram
+ LLVolume* volume = getVolume();
+ for (S32 i = 0; i < volume->getNumFaces(); ++i)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+ if (face.mVertexBuffer.notNull())
+ { //already cached
+ break;
+ }
+ volume->genBinormals(i);
+ LLFace::cacheFaceInVRAM(face);
+ }
+ }
+
+
return TRUE;
}
+
+
return FALSE;
}
@@ -1246,7 +1257,8 @@ BOOL LLVOVolume::calcLOD()
llround(radius, 0.01f));
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
+ mDrawable->getFace(0))
{
//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail));
@@ -1325,25 +1337,23 @@ void LLVOVolume::updateFaceFlags()
for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
{
LLFace *face = mDrawable->getFace(i);
- if (!face)
+ if (face)
{
- return;
- }
+ BOOL fullbright = getTE(i)->getFullbright();
+ face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
- BOOL fullbright = getTE(i)->getFullbright();
- face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
-
- if (fullbright || (mMaterial == LL_MCODE_LIGHT))
- {
- face->setState(LLFace::FULLBRIGHT);
- }
- if (mDrawable->isLight())
- {
- face->setState(LLFace::LIGHT);
- }
- if (isHUDAttachment())
- {
- face->setState(LLFace::HUD_RENDER);
+ if (fullbright || (mMaterial == LL_MCODE_LIGHT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+ if (mDrawable->isLight())
+ {
+ face->setState(LLFace::LIGHT);
+ }
+ if (isHUDAttachment())
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -1380,6 +1390,8 @@ void LLVOVolume::regenFaces()
for (S32 i = 0; i < mNumFaces; i++)
{
LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
+ if (!facep) continue;
+
facep->setTEOffset(i);
facep->setTexture(getTEImage(i));
facep->setViewerObject(this);
@@ -1416,7 +1428,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED);
-// bool rigged = false;
+ // bool rigged = false;
LLVolume* volume = mRiggedVolume;
if (!volume)
{
@@ -1471,11 +1483,11 @@ void LLVOVolume::preRebuild()
}
}
-void LLVOVolume::updateRelativeXform()
+void LLVOVolume::updateRelativeXform(bool force_identity)
{
if (mVolumeImpl)
{
- mVolumeImpl->updateRelativeXform();
+ mVolumeImpl->updateRelativeXform(force_identity);
return;
}
@@ -1495,15 +1507,16 @@ void LLVOVolume::updateRelativeXform()
mRelativeXform.invert();
mRelativeXformInvTrans.transpose();
}
- else if (drawable->isActive())
+ else if (drawable->isActive() || force_identity)
{
// setup relative transforms
LLQuaternion delta_rot;
LLVector3 delta_pos, delta_scale;
//matrix from local space to parent relative/global space
- delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation();
- delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition();
+ bool use_identity = force_identity || drawable->isSpatialRoot();
+ delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation();
+ delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();
delta_scale = mDrawable->getScale();
// Vertex transform (4x4)
@@ -1604,7 +1617,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
return res;
}
- dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyMesh();
+ }
BOOL compiled = FALSE;
@@ -1617,6 +1634,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged || mFaceMappingChanged )
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
compiled = TRUE;
if (mVolumeChanged)
@@ -1635,6 +1654,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
}
else if ((mLODChanged) || (mSculptChanged))
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
LLVolume *old_volumep, *new_volumep;
F32 old_lod, new_lod;
S32 old_num_faces, new_num_faces ;
@@ -1716,16 +1737,19 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
void LLVOVolume::updateFaceSize(S32 idx)
{
LLFace* facep = mDrawable->getFace(idx);
- if (idx >= getVolume()->getNumVolumeFaces())
+ if (facep)
{
- facep->setSize(0,0, true);
- }
- else
- {
- const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
- facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
- true); // <--- volume faces should be padded for 16-byte alignment
+ if (idx >= getVolume()->getNumVolumeFaces())
+ {
+ facep->setSize(0,0, true);
+ }
+ else
+ {
+ const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
+ facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
+ true); // <--- volume faces should be padded for 16-byte alignment
+ }
}
}
@@ -3098,6 +3122,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
for (S32 i = 0; i < num_faces; ++i)
{
const LLFace* face = drawablep->getFace(i);
+ if (!face) continue;
const LLTextureEntry* te = face->getTextureEntry();
const LLViewerTexture* img = face->getTexture();
@@ -3369,6 +3394,7 @@ F32 LLVOVolume::getBinRadius()
for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
{
LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
!face->canRenderAsMask())
{
@@ -3450,9 +3476,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const
{
LLVector3 ret = pos - getRenderPosition();
ret = ret * ~getRenderRotation();
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
- ret.scaleVec(invObjScale);
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+ ret.scaleVec(invObjScale);
+ }
return ret;
}
@@ -3470,8 +3499,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const
LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const
{
LLVector3 ret = dir;
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- ret.scaleVec(objScale);
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ ret.scaleVec(objScale);
+ }
+
ret = ret * getRenderRotation();
ret += getRenderPosition();
@@ -3592,7 +3625,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
LLFace* face = mDrawable->getFace(face_hit);
- if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
+ if (face &&
+ (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
{
v_end = p;
if (face_hitp != NULL)
@@ -3902,8 +3936,11 @@ bool can_batch_texture(LLFace* facep)
return true;
}
+static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");
+
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{
+ LLFastTimer t(FTM_REGISTER_FACE);
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
@@ -3935,9 +3972,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
const LLMatrix4* model_mat = NULL;
LLDrawable* drawable = facep->getDrawable();
- if (drawable->isActive())
+
+ if (drawable->isState(LLDrawable::ANIMATED_CHILD))
{
- model_mat = &(drawable->getRenderMatrix());
+ model_mat = &drawable->getWorldMatrix();
+ }
+ else if (drawable->isActive())
+ {
+ model_mat = &drawable->getRenderMatrix();
}
else
{
@@ -3948,6 +3990,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
+ //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
+
U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
LLViewerTexture* tex = facep->getTexture();
@@ -4041,8 +4085,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
-static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info");
static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
{
@@ -4073,6 +4118,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -4084,19 +4131,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
{
- LLFastTimer ftm(FTM_REBUILD_VBO);
- LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
-
rebuildMesh(group);
}
return;
}
- group->mBuilt = 1.f;
- LLFastTimer ftm(FTM_REBUILD_VBO);
-
- LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
+ LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+ group->mBuilt = 1.f;
+
LLVOAvatar* pAvatarVO = NULL;
LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
@@ -4145,359 +4188,375 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
bool emissive = false;
- //get all the faces into a list
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
-
- if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST);
+
+ //get all the faces into a list
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- continue;
- }
+ LLDrawable* drawablep = *drawable_iter;
+
+ if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ {
+ continue;
+ }
- if (drawablep->isAnimating())
- { //fall back to stream draw for animating verts
- useage = GL_STREAM_DRAW_ARB;
- }
+ if (drawablep->isAnimating())
+ { //fall back to stream draw for animating verts
+ useage = GL_STREAM_DRAW_ARB;
+ }
- LLVOVolume* vobj = drawablep->getVOVolume();
+ LLVOVolume* vobj = drawablep->getVOVolume();
- if (!vobj)
- {
- continue;
- }
+ if (!vobj)
+ {
+ continue;
+ }
- if (vobj->isMesh() &&
- (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
- {
- continue;
- }
+ if (vobj->isMesh() &&
+ (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
+ {
+ continue;
+ }
- LLVolume* volume = vobj->getVolume();
- if (volume)
- {
- const LLVector3& scale = vobj->getScale();
- group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
- }
+ LLVolume* volume = vobj->getVolume();
+ if (volume)
+ {
+ const LLVector3& scale = vobj->getScale();
+ group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
+ }
- llassert_always(vobj);
- vobj->updateTextureVirtualSize(true);
- vobj->preRebuild();
+ llassert_always(vobj);
+ vobj->updateTextureVirtualSize(true);
+ vobj->preRebuild();
- drawablep->clearState(LLDrawable::HAS_ALPHA);
+ drawablep->clearState(LLDrawable::HAS_ALPHA);
- bool rigged = vobj->isAttachment() &&
- vobj->isMesh() &&
- gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
+ bool rigged = vobj->isAttachment() &&
+ vobj->isMesh() &&
+ gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
- bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
+ bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
- bool is_rigged = false;
+ bool is_rigged = false;
- //for each face
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i);
+ //for each face
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ LLFace* facep = drawablep->getFace(i);
+ if (!facep)
+ {
+ continue;
+ }
- //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
- // batch, it will recover its vertex buffer reference from the spatial group
- facep->setVertexBuffer(NULL);
+ //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
+ // batch, it will recover its vertex buffer reference from the spatial group
+ facep->setVertexBuffer(NULL);
- //sum up face verts and indices
- drawablep->updateFaceSize(i);
+ //sum up face verts and indices
+ drawablep->updateFaceSize(i);
- if (rigged)
- {
- if (!facep->isState(LLFace::RIGGED))
- { //completely reset vertex buffer
- facep->clearVertexBuffer();
- }
+ if (rigged)
+ {
+ if (!facep->isState(LLFace::RIGGED))
+ { //completely reset vertex buffer
+ facep->clearVertexBuffer();
+ }
- facep->setState(LLFace::RIGGED);
- is_rigged = true;
+ facep->setState(LLFace::RIGGED);
+ is_rigged = true;
- //get drawpool of avatar with rigged face
- LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
+ //get drawpool of avatar with rigged face
+ LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
- //Determine if we've received skininfo that contains an
- //alternate bind matrix - if it does then apply the translational component
- //to the joints of the avatar.
- bool pelvisGotSet = false;
+ //Determine if we've received skininfo that contains an
+ //alternate bind matrix - if it does then apply the translational component
+ //to the joints of the avatar.
+ bool pelvisGotSet = false;
- if ( pAvatarVO )
- {
- LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
- const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
-
- if ( pSkinData )
+ if ( pAvatarVO )
{
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- const F32 pelvisZOffset = pSkinData->mPelvisOffset;
- bool fullRig = (jointCnt>=20) ? true : false;
- if ( fullRig )
- {
- for ( int i=0; i<jointCnt; ++i )
+ LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+
+ if ( pSkinData )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( bindCnt > 0 )
+ {
+ const int jointCnt = pSkinData->mJointNames.size();
+ const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+ bool fullRig = (jointCnt>=20) ? true : false;
+ if ( fullRig )
{
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
- LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
- {
- pJoint->setId( currentId );
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
- //Set the joint position
- pJoint->storeCurrentXform( jointPos );
- //If joint is a pelvis then handle old/new pelvis to foot values
- if ( lookingForJoint == "mPelvis" )
- {
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
+ LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
+ if ( pJoint && pJoint->getId() != currentId )
+ {
+ pJoint->setId( currentId );
+ const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ //Set the joint position
pJoint->storeCurrentXform( jointPos );
- if ( !pAvatarVO->hasPelvisOffset() )
- {
- pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
- //Trigger to rebuild viewer AV
- pelvisGotSet = true;
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if ( lookingForJoint == "mPelvis" )
+ {
+ pJoint->storeCurrentXform( jointPos );
+ if ( !pAvatarVO->hasPelvisOffset() )
+ {
+ pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
+ //Trigger to rebuild viewer AV
+ pelvisGotSet = true;
+ }
}
- }
+ }
}
- }
- }
+ }
+ }
}
}
- }
- //If we've set the pelvis to a new position we need to also rebuild some information that the
- //viewer does at launch (e.g. body size etc.)
- if ( pelvisGotSet )
- {
- pAvatarVO->postPelvisSetRecalc();
- }
-
- if (pool)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
-
- //remove face from old pool if it exists
- LLDrawPool* old_pool = facep->getPool();
- if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+ //If we've set the pelvis to a new position we need to also rebuild some information that the
+ //viewer does at launch (e.g. body size etc.)
+ if ( pelvisGotSet )
{
- ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+ pAvatarVO->postPelvisSetRecalc();
}
- //add face to new pool
- LLViewerTexture* tex = facep->getTexture();
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
-
- if (type == LLDrawPool::POOL_ALPHA)
+ if (pool)
{
- if (te->getColor().mV[3] > 0.f)
+ const LLTextureEntry* te = facep->getTextureEntry();
+
+ //remove face from old pool if it exists
+ LLDrawPool* old_pool = facep->getPool();
+ if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+ {
+ ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+ }
+
+ //add face to new pool
+ LLViewerTexture* tex = facep->getTexture();
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ if (te->getColor().mV[3] > 0.f)
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ }
+ }
+ }
+ else if (te->getShiny())
{
if (te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ if (LLPipeline::sRenderDeferred)
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ }
}
}
- }
- else if (te->getShiny())
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
- }
else
{
- if (LLPipeline::sRenderDeferred)
+ if (te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
- }
- else
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
- }
- else
+
+ if (te->getGlow())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
}
- }
-
- if (te->getGlow())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
- }
- if (LLPipeline::sRenderDeferred)
- {
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ if (LLPipeline::sRenderDeferred)
{
- if (te->getBumpmap())
+ if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ if (te->getBumpmap())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ }
}
}
}
- }
- continue;
- }
- else
- {
- if (facep->isState(LLFace::RIGGED))
- { //face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
- if (pool)
- {
- pool->removeRiggedFace(facep);
+ continue;
+ }
+ else
+ {
+ if (facep->isState(LLFace::RIGGED))
+ { //face is not rigged but used to be, remove from rigged face pool
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ if (pool)
+ {
+ pool->removeRiggedFace(facep);
+ }
+ facep->clearState(LLFace::RIGGED);
}
- facep->clearState(LLFace::RIGGED);
}
- }
-
- if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
- {
- facep->clearVertexBuffer();
- continue;
- }
- cur_total += facep->getGeomCount();
-
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
- LLViewerTexture* tex = facep->getTexture();
-
- if (te->getGlow() >= 1.f/255.f)
+ if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
{
- emissive = true;
+ facep->clearVertexBuffer();
+ continue;
}
- if (facep->isState(LLFace::TEXTURE_ANIM))
- {
- if (!vobj->mTexAnimMode)
- {
- facep->clearState(LLFace::TEXTURE_ANIM);
- }
- }
+ cur_total += facep->getGeomCount();
- BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
- if (type != LLDrawPool::POOL_ALPHA && force_simple)
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
{
- type = LLDrawPool::POOL_SIMPLE;
- }
- facep->setPoolType(type);
+ const LLTextureEntry* te = facep->getTextureEntry();
+ LLViewerTexture* tex = facep->getTexture();
- if (vobj->isHUDAttachment())
- {
- facep->setState(LLFace::FULLBRIGHT);
- }
+ if (te->getGlow() >= 1.f/255.f)
+ {
+ emissive = true;
+ }
- if (vobj->mTextureAnimp && vobj->mTexAnimMode)
- {
- if (vobj->mTextureAnimp->mFace <= -1)
+ if (facep->isState(LLFace::TEXTURE_ANIM))
{
- S32 face;
- for (face = 0; face < vobj->getNumTEs(); face++)
+ if (!vobj->mTexAnimMode)
{
- drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM);
+ facep->clearState(LLFace::TEXTURE_ANIM);
}
}
- else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+
+ BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ if (type != LLDrawPool::POOL_ALPHA && force_simple)
{
- drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM);
+ type = LLDrawPool::POOL_SIMPLE;
}
- }
+ facep->setPoolType(type);
- if (type == LLDrawPool::POOL_ALPHA)
- {
- if (facep->canRenderAsMask())
- { //can be treated as alpha mask
- simple_faces.push_back(facep);
- }
- else
+ if (vobj->isHUDAttachment())
{
- if (te->getColor().mV[3] > 0.f)
- { //only treat as alpha in the pipeline if < 100% transparent
- drawablep->setState(LLDrawable::HAS_ALPHA);
- }
- alpha_faces.push_back(facep);
+ facep->setState(LLFace::FULLBRIGHT);
}
- }
- else
- {
- if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+
+ if (vobj->mTextureAnimp && vobj->mTexAnimMode)
{
- facep->mLastUpdateTime = gFrameTimeSeconds;
+ if (vobj->mTextureAnimp->mFace <= -1)
+ {
+ S32 face;
+ for (face = 0; face < vobj->getNumTEs(); face++)
+ {
+ LLFace * facep = drawablep->getFace(face);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
+ }
+ else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+ {
+ LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
}
- if (gPipeline.canUseWindLightShadersOnObjects()
- && LLPipeline::sRenderBump)
+ if (type == LLDrawPool::POOL_ALPHA)
{
- if (te->getBumpmap())
- { //needs normal + binormal
- bump_faces.push_back(facep);
- }
- else if (te->getShiny() || !te->getFullbright())
- { //needs normal
+ if (facep->canRenderAsMask())
+ { //can be treated as alpha mask
simple_faces.push_back(facep);
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getColor().mV[3] > 0.f)
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ }
+ alpha_faces.push_back(facep);
}
}
else
{
- if (te->getBumpmap() && LLPipeline::sRenderBump)
- { //needs normal + binormal
- bump_faces.push_back(facep);
+ if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+ {
+ facep->mLastUpdateTime = gFrameTimeSeconds;
}
- else if ((te->getShiny() && LLPipeline::sRenderBump) ||
- !(te->getFullbright() || bake_sunlight))
- { //needs normal
- simple_faces.push_back(facep);
+
+ if (gPipeline.canUseWindLightShadersOnObjects()
+ && LLPipeline::sRenderBump)
+ {
+ if (te->getBumpmap())
+ { //needs normal + binormal
+ bump_faces.push_back(facep);
+ }
+ else if (te->getShiny() || !te->getFullbright())
+ { //needs normal
+ simple_faces.push_back(facep);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ fullbright_faces.push_back(facep);
+ }
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getBumpmap() && LLPipeline::sRenderBump)
+ { //needs normal + binormal
+ bump_faces.push_back(facep);
+ }
+ else if ((te->getShiny() && LLPipeline::sRenderBump) ||
+ !(te->getFullbright() || bake_sunlight))
+ { //needs normal
+ simple_faces.push_back(facep);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ fullbright_faces.push_back(facep);
+ }
}
}
}
+ else
+ { //face has no renderable geometry
+ facep->clearVertexBuffer();
+ }
}
- else
- { //face has no renderable geometry
- facep->clearVertexBuffer();
- }
- }
- if (is_rigged)
- {
- drawablep->setState(LLDrawable::RIGGED);
- }
- else
- {
- drawablep->clearState(LLDrawable::RIGGED);
+ if (is_rigged)
+ {
+ drawablep->setState(LLDrawable::RIGGED);
+ }
+ else
+ {
+ drawablep->clearState(LLDrawable::RIGGED);
+ }
}
}
@@ -4539,7 +4598,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (!LLPipeline::sDelayVBUpdate)
{
//drawables have been rebuilt, clear rebuild status
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
drawablep->clearState(LLDrawable::REBUILD_ALL);
@@ -4564,31 +4623,35 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
{
- LLFastTimer tm(FTM_VOLUME_GEOM);
+ LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
+
S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
group->mBuilt = 1.f;
std::set<LLVertexBuffer*> mapped_buffers;
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);
LLDrawable* drawablep = *drawable_iter;
- if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
+ if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
LLVolume* volume = vobj->getVolume();
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
@@ -4598,8 +4661,15 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- face->getGeometryVolume(*volume, face->getTEOffset(),
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
+ llassert(!face->isState(LLFace::RIGGED));
+
+ if (!face->getGeometryVolume(*volume, face->getTEOffset(),
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
+ { //something's gone wrong with the vertex buffer accounting, rebuild this group
+ group->dirtyGeom();
+ gPipeline.markRebuild(group, TRUE);
+ }
+
if (buff->isLocked())
{
@@ -4608,6 +4678,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
}
}
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform();
+ }
+
drawablep->clearState(LLDrawable::REBUILD_ALL);
}
@@ -4630,16 +4706,19 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
{
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
LLFace* face = drawablep->getFace(i);
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (face && buff && buff->isLocked())
+ if (face)
{
- buff->flush();
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff && buff->isLocked())
+ {
+ buff->flush();
+ }
}
}
}
@@ -4648,7 +4727,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
}
- llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
+// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
}
struct CompareBatchBreakerModified
@@ -4674,8 +4753,20 @@ struct CompareBatchBreakerModified
}
};
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
+
+
+
+
+
void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
{
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+
U32 buffer_usage = group->mBufferUsage;
#if LL_DARWIN
@@ -4693,15 +4784,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
- if (!distance_sort)
- {
- //sort faces by things that break batches
- std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
- }
- else
{
- //sort faces by distance
- std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ LLFastTimer t(FTM_GEN_DRAW_INFO_SORT);
+ if (!distance_sort)
+ {
+ //sort faces by things that break batches
+ std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
+ }
+ else
+ {
+ //sort faces by distance
+ std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ }
}
bool hud_group = group->isHUDGroup() ;
@@ -4766,57 +4860,86 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
std::vector<LLViewerTexture*> texture_list;
- if (batch_textures)
{
- U8 cur_tex = 0;
- facep->setTextureIndex(cur_tex);
- texture_list.push_back(tex);
-
- //if (can_batch_texture(facep))
+ LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
+ if (batch_textures)
{
- while (i != faces.end())
+ U8 cur_tex = 0;
+ facep->setTextureIndex(cur_tex);
+ texture_list.push_back(tex);
+
+ //if (can_batch_texture(facep))
{
- facep = *i;
- if (facep->getTexture() != tex)
+ while (i != faces.end())
{
- if (distance_sort)
- { //textures might be out of order, see if texture exists in current batch
- bool found = false;
- for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
- {
- if (facep->getTexture() == texture_list[tex_idx])
+ facep = *i;
+ if (facep->getTexture() != tex)
+ {
+ if (distance_sort)
+ { //textures might be out of order, see if texture exists in current batch
+ bool found = false;
+ for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
{
- cur_tex = tex_idx;
- found = true;
- break;
+ if (facep->getTexture() == texture_list[tex_idx])
+ {
+ cur_tex = tex_idx;
+ found = true;
+ break;
+ }
}
- }
- if (!found)
+ if (!found)
+ {
+ cur_tex = texture_list.size();
+ }
+ }
+ else
{
- cur_tex = texture_list.size();
+ cur_tex++;
}
- }
- else
- {
- cur_tex++;
- }
- if (!can_batch_texture(facep))
- { //face is bump mapped or has an animated texture matrix -- can't
- //batch more than 1 texture at a time
- break;
+ if (!can_batch_texture(facep))
+ { //face is bump mapped or has an animated texture matrix -- can't
+ //batch more than 1 texture at a time
+ break;
+ }
+
+ if (cur_tex >= texture_index_channels)
+ { //cut batches when index channels are depleted
+ break;
+ }
+
+ tex = facep->getTexture();
+
+ texture_list.push_back(tex);
}
- if (cur_tex >= texture_index_channels)
- { //cut batches when index channels are depleted
+ if (geom_count + facep->getGeomCount() > max_vertices)
+ { //cut batches on geom count too big
break;
}
- tex = facep->getTexture();
+ ++i;
+ index_count += facep->getIndicesCount();
+ geom_count += facep->getGeomCount();
- texture_list.push_back(tex);
+ facep->setTextureIndex(cur_tex);
}
+ }
+
+ tex = texture_list[0];
+ }
+ else
+ {
+ while (i != faces.end() &&
+ (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
+ {
+ facep = *i;
+
+
+ //face has no texture index
+ facep->mDrawInfo = NULL;
+ facep->setTextureIndex(255);
if (geom_count + facep->getGeomCount() > max_vertices)
{ //cut batches on geom count too big
@@ -4826,69 +4949,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
++i;
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
-
- facep->setTextureIndex(cur_tex);
}
}
-
- tex = texture_list[0];
}
- else
- {
- while (i != faces.end() &&
- (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
- {
- facep = *i;
-
-
- //face has no texture index
- facep->mDrawInfo = NULL;
- facep->setTextureIndex(255);
-
- if (geom_count + facep->getGeomCount() > max_vertices)
- { //cut batches on geom count too big
- break;
- }
- ++i;
- index_count += facep->getIndicesCount();
- geom_count += facep->getGeomCount();
- }
- }
-
- //create/delete/resize vertex buffer if needed
+ //create vertex buffer
LLVertexBuffer* buffer = NULL;
- { //try to find a buffer to reuse
- LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
-
- if (found_iter != group->mBufferMap[mask].end())
- {
- if ((U32) buffer_index < found_iter->second.size())
- {
- buffer = found_iter->second[buffer_index];
- }
- }
- }
-
- if (!buffer || !buffer->isWriteable())
- { //create new buffer if needed
+ {
+ LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE);
buffer = createVertexBuffer(mask, buffer_usage);
buffer->allocateBuffer(geom_count, index_count, TRUE);
}
- else
- { //resize pre-existing buffer
- if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage ||
- buffer->getTypeMask() != mask)
- {
- buffer = createVertexBuffer(mask, buffer_usage);
- buffer->allocateBuffer(geom_count, index_count, TRUE);
- }
- else
- {
- buffer->resizeBuffer(geom_count, index_count);
- }
- }
group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
@@ -4922,10 +4994,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
LLVOVolume* vobj = drawablep->getVOVolume();
LLVolume* volume = vobj->getVolume();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
U32 te_idx = facep->getTEOffset();
- facep->getGeometryVolume(*volume, te_idx,
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset);
+ llassert(!facep->isState(LLFace::RIGGED));
+
+ if (!facep->getGeometryVolume(*volume, te_idx,
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))
+ {
+ llwarns << "Failed to get geometry for face!" << llendl;
+ }
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(false);
+ }
}
}
@@ -5089,7 +5176,8 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
mFaceList.clear();
//for each drawable
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -5109,17 +5197,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
//sum up face verts and indices
drawablep->updateFaceSize(i);
LLFace* facep = drawablep->getFace(i);
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
+ if (facep)
{
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
- llassert(facep->getIndicesCount() < 65536);
- //remember face (for sorting)
- mFaceList.push_back(facep);
- }
- else
- {
- facep->clearVertexBuffer();
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA &&
+ facep->getGeomCount() + vertex_count <= 65536)
+ {
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ //remember face (for sorting)
+ mFaceList.push_back(facep);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
}
}
}