summaryrefslogtreecommitdiff
path: root/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r--indra/newview/llvoavatar.cpp246
1 files changed, 50 insertions, 196 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 89ce889a61..9af1198df1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -696,10 +696,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
}
- mDirtyMesh = TRUE; // Dirty geometry, need to regenerate.
+ mDirtyMesh = 2; // Dirty geometry, need to regenerate.
mMeshTexturesDirty = FALSE;
- mShadow0Facep = NULL;
- mShadow1Facep = NULL;
mHeadp = NULL;
mIsBuilt = FALSE;
@@ -735,12 +733,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRippleTimeLast = 0.f;
- mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c");
-
- // GL NOT ACTIVE HERE
- //gGL.getTexUnit(0)->bind(mShadowImagep.get());
- //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
-
mInAir = FALSE;
mStepOnLand = TRUE;
@@ -1969,7 +1961,7 @@ void LLVOAvatar::updateMeshData()
}
if(num_vertices < 1)//skip empty meshes
{
- break ;
+ continue ;
}
if(last_v_num > 0)//put the last inserted part into next vertex buffer.
{
@@ -1991,6 +1983,8 @@ void LLVOAvatar::updateMeshData()
// resize immediately
facep->setSize(num_vertices, num_indices);
+ bool terse_update = false;
+
if(facep->mVertexBuffer.isNull())
{
facep->mVertexBuffer = new LLVertexBufferAvatar();
@@ -1998,8 +1992,16 @@ void LLVOAvatar::updateMeshData()
}
else
{
+ if (facep->mVertexBuffer->getRequestedIndices() == num_indices &&
+ facep->mVertexBuffer->getRequestedVerts() == num_vertices)
+ {
+ terse_update = true;
+ }
+ else
+ {
facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
}
+ }
facep->setGeomIndex(0);
facep->setIndicesIndex(0);
@@ -2013,7 +2015,7 @@ void LLVOAvatar::updateMeshData()
for(S32 k = j ; k < part_index ; k++)
{
- mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR);
+ mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update);
}
stop_glerror();
@@ -2423,12 +2425,6 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
LLJoint::sNumUpdates = 0;
LLJoint::sNumTouches = 0;
- // *NOTE: this is necessary for the floating name text above your head.
- if (mDrawable.notNull())
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE);
- }
-
BOOL visible = isVisible() || mNeedsAnimUpdate;
// update attachments positions
@@ -2751,7 +2747,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
{
// update chat bubble
//--------------------------------------------------------------------
- // draw text label over characters head
+ // draw text label over character's head
//--------------------------------------------------------------------
if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME)
{
@@ -3781,13 +3777,20 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
return num_indices;
}
- if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+ LLFace* face = mDrawable->getFace(0);
+
+ bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
+
+ if (needs_rebuild || mDirtyMesh)
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
+ if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
+ {
updateMeshData();
- mDirtyMesh = FALSE;
+ mDirtyMesh = 0;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}
+ }
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
{
@@ -4034,54 +4037,6 @@ U32 LLVOAvatar::renderRigid()
return num_indices;
}
-U32 LLVOAvatar::renderFootShadows()
-{
- U32 num_indices = 0;
-
- if (!mIsBuilt)
- {
- return 0;
- }
-
- if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
- {
- return 0;
- }
-
- if (!mIsBuilt)
- {
- return 0;
- }
-
- // Don't render foot shadows if your lower body is completely invisible.
- // (non-humanoid avatars rule!)
- if (!isTextureVisible(TEX_LOWER_BAKED))
- {
- return 0;
- }
-
- // Update the shadow, tractor, and text label geometry.
- if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor())
- {
- updateShadowFaces();
- mDrawable->clearState(LLDrawable::REBUILD_SHADOW);
- }
-
- U32 foot_mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0;
-
- LLGLDepthTest test(GL_TRUE, GL_FALSE);
- //render foot shadows
- LLGLEnable blend(GL_BLEND);
- gGL.getTexUnit(0)->bind(mShadowImagep, TRUE);
- glColor4fv(mShadow0Facep->getRenderColor().mV);
- mShadow0Facep->renderIndexed(foot_mask);
- glColor4fv(mShadow1Facep->getRenderColor().mV);
- mShadow1Facep->renderIndexed(foot_mask);
-
- return num_indices;
-}
-
U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
{
if (!mImpostor.isComplete())
@@ -4207,11 +4162,6 @@ void LLVOAvatar::updateTextures()
{
setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));
}
-
- if( render_avatar )
- {
- mShadowImagep->addTextureStats(mPixelArea);
- }
}
@@ -5478,7 +5428,7 @@ BOOL LLVOAvatar::updateJointLODs()
if (res)
{
sNumLODChangesThisFrame++;
- dirtyMesh();
+ dirtyMesh(2);
return TRUE;
}
}
@@ -5502,18 +5452,9 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
mDrawable->addFace(poolp, NULL);
mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
- LLFace *facep;
-
- // Add faces for the foot shadows
- facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
- mShadow0Facep = facep;
-
- facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
- mShadow1Facep = facep;
-
mNumInitFaces = mDrawable->getNumFaces() ;
- dirtyMesh();
+ dirtyMesh(2);
return mDrawable;
}
@@ -5553,107 +5494,6 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
}
//-----------------------------------------------------------------------------
-// updateShadowFaces()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::updateShadowFaces()
-{
- LLFace *face0p = mShadow0Facep;
- LLFace *face1p = mShadow1Facep;
-
- //
- // render avatar shadows
- //
- if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD)
- {
- face0p->setSize(0, 0);
- face1p->setSize(0, 0);
- return;
- }
-
- LLSprite sprite(mShadowImagep.notNull() ? mShadowImagep->getID() : LLUUID::null);
- sprite.setFollow(FALSE);
- const F32 cos_angle = gSky.getSunDirection().mV[2];
- F32 cos_elev = sqrt(1 - cos_angle * cos_angle);
- if (cos_angle < 0) cos_elev = -cos_elev;
- sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f);
- LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f);
-
- if (mShadowImagep->hasGLTexture())
- {
- LLVector3 normal;
- LLVector3d shadow_pos;
- LLVector3 shadow_pos_agent;
- F32 foot_height;
-
- if (mFootLeftp)
- {
- LLVector3 joint_world_pos = mFootLeftp->getWorldPosition();
- // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
- // but we make an explicit ray trace call in expectation of future improvements
- resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
- gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
- shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
- foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
-
- // Pull sprite in direction of surface normal
- shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
-
- // Render sprite
- sprite.setNormal(normal);
- if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
- {
- sprite.setColor(0.f, 0.f, 0.f, 0.f);
- }
- else
- {
- sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
- }
- sprite.setPosition(shadow_pos_agent);
-
- LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos;
- //foot_to_knee.normalize();
- foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
- sprite.setYaw(azimuth(sun_vec - foot_to_knee));
-
- sprite.updateFace(*face0p);
- }
-
- if (mFootRightp)
- {
- LLVector3 joint_world_pos = mFootRightp->getWorldPosition();
- // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
- // but we make an explicit ray trace call in expectation of future improvements
- resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
- gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
- shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
- foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
-
- // Pull sprite in direction of surface normal
- shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
-
- // Render sprite
- sprite.setNormal(normal);
- if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
- {
- sprite.setColor(0.f, 0.f, 0.f, 0.f);
- }
- else
- {
- sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
- }
- sprite.setPosition(shadow_pos_agent);
-
- LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos;
- //foot_to_knee.normalize();
- foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
- sprite.setYaw(azimuth(sun_vec - foot_to_knee));
-
- sprite.updateFace(*face1p);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
// updateSexDependentLayerSets()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
@@ -5668,9 +5508,12 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
//-----------------------------------------------------------------------------
void LLVOAvatar::dirtyMesh()
{
- mDirtyMesh = TRUE;
+ dirtyMesh(1);
+}
+void LLVOAvatar::dirtyMesh(S32 priority)
+{
+ mDirtyMesh = llmax(mDirtyMesh, priority);
}
-
//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
@@ -5704,6 +5547,7 @@ BOOL LLVOAvatar::setParent(LLViewerObject* parent)
void LLVOAvatar::addChild(LLViewerObject *childp)
{
+ childp->extractAttachmentItemID(); // find the inventory item this object is associated with.
LLViewerObject::addChild(childp);
if (childp->mDrawable)
{
@@ -5793,6 +5637,15 @@ BOOL LLVOAvatar::canAttachMoreObjects() const
}
//-----------------------------------------------------------------------------
+// canAttachMoreObjects()
+// Returns true if we can attach <n> more objects.
+//-----------------------------------------------------------------------------
+BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const
+{
+ return (getNumAttachments() + n) <= MAX_AGENT_ATTACHMENTS;
+}
+
+//-----------------------------------------------------------------------------
// lazyAttach()
//-----------------------------------------------------------------------------
void LLVOAvatar::lazyAttach()
@@ -6244,10 +6097,14 @@ void LLVOAvatar::updateMeshTextures()
// When an avatar is changing clothes and not in Appearance mode,
// use the last-known good baked texture until it finish the first
// render of the new layerset.
+
+ const BOOL layerset_invalid = !mBakedTextureDatas[i].mTexLayerSet
+ || !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()
+ || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable();
+
use_lkg_baked_layer[i] = (!is_layer_baked[i]
&& (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR)
- && mBakedTextureDatas[i].mTexLayerSet
- && !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized());
+ && layerset_invalid);
if (use_lkg_baked_layer[i])
{
mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
@@ -7935,18 +7792,15 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (facep->mVertexBuffer.isNull() ||
- (LLVertexBuffer::sEnableVBOs &&
- ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
- (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))))
+ if (facep->mVertexBuffer.isNull())
{
- mDirtyMesh = TRUE;
+ dirtyMesh(2);
}
- if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+ if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
updateMeshData();
- mDirtyMesh = FALSE;
+ mDirtyMesh = 0;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}