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.cpp436
1 files changed, 358 insertions, 78 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f1934933b5..1f6d686a86 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -64,6 +64,8 @@
#include "llkeyframefallmotion.h"
#include "llkeyframestandmotion.h"
#include "llkeyframewalkmotion.h"
+#include "llmanipscale.h" // for get_default_max_prim_scale()
+#include "llmeshrepository.h"
#include "llmutelist.h"
#include "llmoveview.h"
#include "llnotificationsutil.h"
@@ -81,6 +83,7 @@
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
+#include "llviewershadermgr.h"
#include "llviewerstats.h"
#include "llvoavatarself.h"
#include "llvovolume.h"
@@ -679,12 +682,14 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mTexHairColor( NULL ),
mTexEyeColor( NULL ),
mNeedsSkin(FALSE),
+ mLastSkinTime(0.f),
mUpdatePeriod(1),
mFullyLoaded(FALSE),
mPreviousFullyLoaded(FALSE),
mFullyLoadedInitialized(FALSE),
mSupportsAlphaLayers(FALSE),
- mLoadedCallbacksPaused(FALSE)
+ mLoadedCallbacksPaused(FALSE),
+ mHasPelvisOffset( FALSE )
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
//VTResume(); // VTune
@@ -759,6 +764,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRuthTimer.reset();
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
+ mPelvisOffset = LLVector3(0.0f,0.0f,0.0f);
+ mLastPelvisToFoot = 0.0f;
+ mPelvisFixup = 0.0f;
+ mLastPelvisFixup = 0.0f;
}
//------------------------------------------------------------------------
@@ -1322,7 +1331,17 @@ const LLVector3 LLVOAvatar::getRenderPosition() const
}
else if (isRoot())
{
- return mDrawable->getPositionAgent();
+ if ( !mHasPelvisOffset )
+ {
+ return mDrawable->getPositionAgent();
+ }
+ else
+ {
+ //Apply a pelvis fixup (as defined by the avs skin)
+ LLVector3 pos = mDrawable->getPositionAgent();
+ pos[VZ] += mPelvisFixup;
+ return pos;
+ }
}
else
{
@@ -1335,42 +1354,47 @@ void LLVOAvatar::updateDrawable(BOOL force_damped)
clearChanged(SHIFTED);
}
-void LLVOAvatar::onShift(const LLVector3& shift_vector)
+void LLVOAvatar::onShift(const LLVector4a& shift_vector)
{
- mLastAnimExtents[0] += shift_vector;
- mLastAnimExtents[1] += shift_vector;
+ const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
+ mLastAnimExtents[0] += shift;
+ mLastAnimExtents[1] += shift;
mNeedsImpostorUpdate = TRUE;
mNeedsAnimUpdate = TRUE;
}
-void LLVOAvatar::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
+void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
{
if (isImpostor() && !needsImpostorUpdate())
{
LLVector3 delta = getRenderPosition() -
- ((LLVector3(mDrawable->getPositionGroup())-mImpostorOffset));
+ ((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset));
- newMin = mLastAnimExtents[0] + delta;
- newMax = mLastAnimExtents[1] + delta;
+ newMin.load3( (mLastAnimExtents[0] + delta).mV);
+ newMax.load3( (mLastAnimExtents[1] + delta).mV);
}
else
{
getSpatialExtents(newMin,newMax);
- mLastAnimExtents[0] = newMin;
- mLastAnimExtents[1] = newMax;
- LLVector3 pos_group = (newMin+newMax)*0.5f;
- mImpostorOffset = pos_group-getRenderPosition();
+ mLastAnimExtents[0].set(newMin.getF32ptr());
+ mLastAnimExtents[1].set(newMax.getF32ptr());
+ LLVector4a pos_group;
+ pos_group.setAdd(newMin,newMax);
+ pos_group.mul(0.5f);
+ mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition();
mDrawable->setPositionGroup(pos_group);
}
}
-void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
+void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
- LLVector3 buffer(0.25f, 0.25f, 0.25f);
- LLVector3 pos = getRenderPosition();
- newMin = pos - buffer;
- newMax = pos + buffer;
- float max_attachment_span = DEFAULT_MAX_PRIM_SCALE * 5.0f;
+ LLVector4a buffer(0.25f);
+ LLVector4a pos;
+ pos.load3(getRenderPosition().mV);
+ newMin.setSub(pos, buffer);
+ newMax.setAdd(pos, buffer);
+
+ float max_attachment_span = get_default_max_prim_scale() * 5.0f;
//stretch bounding box by joint positions
for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i)
@@ -1378,12 +1402,20 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
LLPolyMesh* mesh = i->second;
for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++)
{
- update_min_max(newMin, newMax,
- mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation());
+ LLVector4a trans;
+ trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV);
+ update_min_max(newMin, newMax, trans);
}
}
- mPixelArea = LLPipeline::calcPixelArea((newMin+newMax)*0.5f, (newMax-newMin)*0.5f, *LLViewerCamera::getInstance());
+ LLVector4a center, size;
+ center.setAdd(newMin, newMax);
+ center.mul(0.5f);
+
+ size.setSub(newMax,newMin);
+ size.mul(0.5f);
+
+ mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
//stretch bounding box by attachments
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
@@ -1405,20 +1437,22 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
if (attached_object && !attached_object->isHUDAttachment())
{
LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
+ if (drawable && !drawable->isState(LLDrawable::RIGGED))
{
LLSpatialBridge* bridge = drawable->getSpatialBridge();
if (bridge)
{
- const LLVector3* ext = bridge->getSpatialExtents();
- LLVector3 distance = (ext[1] - ext[0]);
+ const LLVector4a* ext = bridge->getSpatialExtents();
+ LLVector4a distance;
+ distance.setSub(ext[1], ext[0]);
+ LLVector4a max_span(max_attachment_span);
+
+ S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
// Only add the prim to spatial extents calculations if it isn't a megaprim.
// max_attachment_span calculated at the start of the function
// (currently 5 times our max prim size)
- if (distance.mV[0] < max_attachment_span
- && distance.mV[1] < max_attachment_span
- && distance.mV[2] < max_attachment_span)
+ if (lt == 0x7)
{
update_min_max(newMin,newMax,ext[0]);
update_min_max(newMin,newMax,ext[1]);
@@ -1430,8 +1464,9 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
}
//pad bounding box
- newMin -= buffer;
- newMax += buffer;
+
+ newMin.sub(buffer);
+ newMax.add(buffer);
}
//-----------------------------------------------------------------------------
@@ -1606,7 +1641,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
info->mRot.mV[VZ], LLQuaternion::XYZ));
joint->setScale(info->mScale);
-
+ joint->setDefaultFromCurrentXform();
+
if (info->mIsJoint)
{
joint->setSkinOffset( info->mPivot );
@@ -1984,26 +2020,29 @@ void LLVOAvatar::updateMeshData()
bool terse_update = false;
- if(facep->mVertexBuffer.isNull())
+ facep->setGeomIndex(0);
+ facep->setIndicesIndex(0);
+
+ LLVertexBuffer* buff = facep->getVertexBuffer();
+ if(!facep->getVertexBuffer())
{
- facep->mVertexBuffer = new LLVertexBufferAvatar();
- facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
+ buff = new LLVertexBufferAvatar();
+ buff->allocateBuffer(num_vertices, num_indices, TRUE);
+ facep->setVertexBuffer(buff);
}
else
{
- if (facep->mVertexBuffer->getRequestedIndices() == num_indices &&
- facep->mVertexBuffer->getRequestedVerts() == num_vertices)
+ if (buff->getRequestedIndices() == num_indices &&
+ buff->getRequestedVerts() == num_vertices)
{
terse_update = true;
}
else
{
- facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
- }
+ buff->resizeBuffer(num_vertices, num_indices);
+ }
}
-
- facep->setGeomIndex(0);
- facep->setIndicesIndex(0);
+
// This is a hack! Avatars have their own pool, so we are detecting
// the case of more than one avatar in the pool (thus > 0 instead of >= 0)
@@ -2018,7 +2057,7 @@ void LLVOAvatar::updateMeshData()
}
stop_glerror();
- facep->mVertexBuffer->setBuffer(0);
+ buff->setBuffer(0);
if(!f_num)
{
@@ -2386,9 +2425,19 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
// here we get the approximate head position and set as sound source for the voice symbol
// (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
//--------------------------------------------------------------------------------------------
- LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
- mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
+ if ( mIsSitting )
+ {
+ LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
+ mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
+ }
+ else
+ {
+ LLVector3 tagPos = mRoot.getWorldPosition();
+ tagPos[VZ] -= mPelvisToFoot;
+ tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
+ mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
+ }
}//if ( voiceEnabled )
}
@@ -2452,7 +2501,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (isImpostor() && !mNeedsImpostorUpdate)
{
- LLVector3 ext[2];
+ LLVector4a ext[2];
F32 distance;
LLVector3 angle;
@@ -2481,12 +2530,22 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
else
{
+ //VECTORIZE THIS
getSpatialExtents(ext[0], ext[1]);
- if ((ext[1]-mImpostorExtents[1]).length() > 0.05f ||
- (ext[0]-mImpostorExtents[0]).length() > 0.05f)
+ LLVector4a diff;
+ diff.setSub(ext[1], mImpostorExtents[1]);
+ if (diff.getLength3().getF32() > 0.05f)
{
mNeedsImpostorUpdate = TRUE;
}
+ else
+ {
+ diff.setSub(ext[0], mImpostorExtents[0]);
+ if (diff.getLength3().getF32() > 0.05f)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ }
+ }
}
}
}
@@ -2825,10 +2884,8 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
}
LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
- mNameText->setPositionAgent(name_position);
-
- idleUpdateNameTagText(new_name);
-
+ mNameText->setPositionAgent(name_position);
+ idleUpdateNameTagText(new_name);
idleUpdateNameTagAlpha(new_name, alpha);
}
@@ -3114,8 +3171,9 @@ void LLVOAvatar::invalidateNameTags()
if (avatar->isDead()) continue;
avatar->clearNameTag();
- }
- }
+
+ }
+}
// Compute name tag position during idle update
LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
@@ -3134,12 +3192,14 @@ LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
local_camera_up.scaleVec(mBodySize * 0.5f);
local_camera_at.scaleVec(mBodySize * 0.5f);
- LLVector3 name_position = mRoot.getWorldPosition() +
- (local_camera_up * root_rot) -
- (projected_vec(local_camera_at * root_rot, camera_to_av));
+ LLVector3 name_position = mRoot.getWorldPosition();
+ name_position[VZ] -= mPelvisToFoot;
+ name_position[VZ] += (mBodySize[VZ]* 0.55f);
+ name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));
name_position += pixel_up_vec * 15.f;
+
return name_position;
- }
+}
void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
{
@@ -3260,20 +3320,28 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
mTimeVisible.reset();
}
-
+
//--------------------------------------------------------------------
// the rest should only be done occasionally for far away avatars
//--------------------------------------------------------------------
if (visible && !isSelf() && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
{
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
+ LLVector4a size;
+ size.setSub(ext[1],ext[0]);
+ F32 mag = size.getLength3().getF32()*0.5f;
+
F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
if (LLMuteList::getInstance()->isMuted(getID()))
{ // muted avatars update at 16 hz
mUpdatePeriod = 16;
}
- else if (mVisibilityRank <= LLVOAvatar::sMaxVisible)
+ else if (mVisibilityRank <= LLVOAvatar::sMaxVisible ||
+ mDrawable->mDistanceWRTCamera < 1.f + mag)
{ //first 25% of max visible avatars are not impostored
+ //also, don't impostor avatars whose bounding box may be penetrating the
+ //impostor camera near clip plane
mUpdatePeriod = 1;
}
else if (mVisibilityRank > LLVOAvatar::sMaxVisible * 4)
@@ -3384,7 +3452,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
- F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
+ F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) ||
foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE);
@@ -3398,13 +3466,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// of the agent's physical representation
root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
-
LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
if (newPosition != mRoot.getXform()->getWorldPosition())
{
mRoot.touch();
- mRoot.setWorldPosition(newPosition ); // regular update
+ mRoot.setWorldPosition( newPosition ); // regular update
}
@@ -3680,7 +3747,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
return TRUE;
}
-
//-----------------------------------------------------------------------------
// updateHeadOffset()
//-----------------------------------------------------------------------------
@@ -3705,7 +3771,41 @@ void LLVOAvatar::updateHeadOffset()
mHeadOffset = lerp(midEyePt, mHeadOffset, u);
}
}
-
+//------------------------------------------------------------------------
+// setPelvisOffset
+//------------------------------------------------------------------------
+void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, F32 pelvisFixup )
+{
+ mHasPelvisOffset = hasOffset;
+ if ( mHasPelvisOffset )
+ {
+ //Store off last pelvis to foot value
+ mLastPelvisToFoot = mPelvisToFoot;
+ mPelvisOffset = offsetAmount;
+ mLastPelvisFixup = mPelvisFixup;
+ mPelvisFixup = pelvisFixup;
+ }
+}
+//------------------------------------------------------------------------
+// postPelvisSetRecalc
+//------------------------------------------------------------------------
+void LLVOAvatar::postPelvisSetRecalc( void )
+{
+ computeBodySize();
+ mRoot.touch();
+ mRoot.updateWorldMatrixChildren();
+ dirtyMesh();
+ updateHeadOffset();
+}
+//------------------------------------------------------------------------
+// pelisPoke
+//------------------------------------------------------------------------
+void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount )
+{
+ mHasPelvisOffset = true;
+ mLastPelvisFixup = mPelvisFixup;
+ mPelvisFixup = pelvisFixupAmount;
+}
//------------------------------------------------------------------------
// updateVisibility()
//------------------------------------------------------------------------
@@ -3855,6 +3955,46 @@ bool LLVOAvatar::shouldAlphaMask()
}
+U32 LLVOAvatar::renderSkinnedAttachments()
+{
+ /*U32 num_indices = 0;
+
+ const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4;
+
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ const LLViewerObject* attached_object = (*attachment_iter);
+ if (attached_object && !attached_object->isHUDAttachment())
+ {
+ const LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable)
+ {
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* face = drawable->getFace(i);
+ if (face->isState(LLFace::RIGGED))
+ {
+
+ }
+ }
+ }
+ }
+
+ return num_indices;*/
+ return 0;
+}
+
//-----------------------------------------------------------------------------
// renderSkinned()
//-----------------------------------------------------------------------------
@@ -3869,7 +4009,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
LLFace* face = mDrawable->getFace(0);
- bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
+ bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
if (needs_rebuild || mDirtyMesh)
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
@@ -3902,8 +4042,9 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
mMeshLOD[MESH_ID_HAIR]->updateJointGeometry();
}
mNeedsSkin = FALSE;
-
- LLVertexBuffer* vb = mDrawable->getFace(0)->mVertexBuffer;
+ mLastSkinTime = gFrameTimeSeconds;
+
+ LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer();
if (vb)
{
vb->setBuffer(0);
@@ -4250,7 +4391,7 @@ void LLVOAvatar::updateTextures()
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
{
- setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));
+ setDebugText(llformat("%4.0f:%4.0f", (F32) sqrt(mMinPixelArea),(F32) sqrt(mMaxPixelArea)));
}
}
@@ -4392,7 +4533,6 @@ void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVec
LLWorld::getInstance()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj);
}
-
void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm)
{
LLVector3d zVec(0.0f, 0.0f, 0.5f);
@@ -4789,6 +4929,80 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
}
//-----------------------------------------------------------------------------
+// resetJointPositions
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetJointPositions( void )
+{
+ for(S32 i = 0; i < (S32)mNumJoints; ++i)
+ {
+ mSkeleton[i].restoreOldXform();
+ mSkeleton[i].setId( LLUUID::null );
+ }
+ mHasPelvisOffset = false;
+ mPelvisFixup = mLastPelvisFixup;
+}
+//-----------------------------------------------------------------------------
+// resetSpecificJointPosition
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
+{
+ LLJoint* pJoint = mRoot.findJoint( name );
+
+ if ( pJoint && pJoint->doesJointNeedToBeReset() )
+ {
+ pJoint->restoreOldXform();
+ pJoint->setId( LLUUID::null );
+ //If we're reseting the pelvis position make sure not to apply offset
+ if ( name == "mPelvis" )
+ {
+ mHasPelvisOffset = false;
+ }
+ }
+ else
+ {
+ llinfos<<"Did not find "<< name.c_str()<<llendl;
+ }
+}
+//-----------------------------------------------------------------------------
+// resetJointPositionsToDefault
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetJointPositionsToDefault( void )
+{
+ const LLVector3& avPos = getCharacterPosition();
+
+ //Reposition the pelvis
+ LLJoint* pPelvis = mRoot.findJoint("mPelvis");
+ if ( pPelvis )
+ {
+ pPelvis->setPosition( avPos + pPelvis->getPosition() );
+ }
+ else
+ {
+ llwarns<<"Can't get pelvis joint."<<llendl;
+ return;
+ }
+
+ //Subsequent joints are relative to pelvis
+ for( S32 i = 0; i < (S32)mNumJoints; ++i )
+ {
+ LLJoint* pJoint = (LLJoint*)&mSkeleton[i];
+ if ( pJoint->doesJointNeedToBeReset() )
+ {
+
+ pJoint->setId( LLUUID::null );
+ //restore joints to default positions, however skip over the pelvis
+ if ( pJoint && pPelvis != pJoint )
+ {
+ pJoint->restoreOldXform();
+ }
+ }
+ }
+ //make sure we don't apply the joint offset
+ mHasPelvisOffset = false;
+ mPelvisFixup = mLastPelvisFixup;
+ postPelvisSetRecalc();
+}
+//-----------------------------------------------------------------------------
// getCharacterPosition()
//-----------------------------------------------------------------------------
LLVector3 LLVOAvatar::getCharacterPosition()
@@ -5445,9 +5659,13 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
return;
}
- const LLVector3* ext = mDrawable->getSpatialExtents();
- LLVector3 center = (ext[1] + ext[0]) * 0.5f;
- LLVector3 size = (ext[1]-ext[0])*0.5f;
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
+ LLVector4a center;
+ center.setAdd(ext[1], ext[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
@@ -5459,7 +5677,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
}
else
{
- F32 radius = size.length();
+ F32 radius = size.getLength3().getF32();
mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG;
}
@@ -5770,6 +5988,52 @@ void LLVOAvatar::resetHUDAttachments()
}
}
+void LLVOAvatar::rebuildRiggedAttachments( void )
+{
+ for ( attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter )
+ {
+ LLViewerJointAttachment* pAttachment = iter->second;
+ LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIterEnd = pAttachment->mAttachedObjects.end();
+
+ for ( LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIter = pAttachment->mAttachedObjects.begin();
+ attachmentIter != attachmentIterEnd; ++attachmentIter)
+ {
+ const LLViewerObject* pAttachedObject = *attachmentIter;
+ if ( pAttachment && pAttachedObject->mDrawable.notNull() )
+ {
+ gPipeline.markRebuild(pAttachedObject->mDrawable);
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// cleanupAttachedMesh()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
+{
+ //If a VO has a skin that we'll reset the joint positions to their default
+ if ( pVO && pVO->mDrawable )
+ {
+ LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
+ if ( pVObj )
+ {
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() );
+ if ( pSkinData )
+ {
+ const int jointCnt = pSkinData->mJointNames.size();
+ bool fullRig = ( jointCnt>=20 ) ? true : false;
+ if ( fullRig )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( bindCnt > 0 )
+ {
+ LLVOAvatar::resetJointPositionsToDefault();
+ }
+ }
+ }
+ }
+ }
+}
//-----------------------------------------------------------------------------
// detachObject()
//-----------------------------------------------------------------------------
@@ -5780,14 +6044,23 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
++iter)
{
LLViewerJointAttachment* attachment = iter->second;
-
+
if (attachment->isObjectAttached(viewer_object))
{
+ cleanupAttachedMesh( viewer_object );
attachment->removeObject(viewer_object);
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
return TRUE;
}
}
+
+ std::vector<LLPointer<LLViewerObject> >::iterator iter = std::find(mPendingAttachment.begin(), mPendingAttachment.end(), viewer_object);
+ if (iter != mPendingAttachment.end())
+ {
+ mPendingAttachment.erase(iter);
+ return TRUE;
+ }
+
return FALSE;
}
@@ -7864,7 +8137,7 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (facep->mVertexBuffer.isNull())
+ if (!facep->getVertexBuffer())
{
dirtyMesh(2);
}
@@ -7876,12 +8149,16 @@ BOOL LLVOAvatar::updateLOD()
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}
-
updateVisibility();
return res;
}
+void LLVOAvatar::updateLODRiggedAttachments( void )
+{
+ updateLOD();
+ rebuildRiggedAttachments();
+}
U32 LLVOAvatar::getPartitionType() const
{
// Avatars merely exist as drawables in the bridge partition
@@ -7933,9 +8210,9 @@ void LLVOAvatar::cacheImpostorValues()
getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance);
}
-void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const
+void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const
{
- const LLVector3* ext = mDrawable->getSpatialExtents();
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
extents[0] = ext[0];
extents[1] = ext[1];
@@ -7998,7 +8275,9 @@ void LLVOAvatar::idleUpdateRenderCost()
}
}
}
+
}
+
// Diagnostic output to identify all avatar-related textures.
// Does not affect rendering cost calculation.
// Could be wrapped in a debug option if output becomes problematic.
@@ -8038,6 +8317,7 @@ void LLVOAvatar::idleUpdateRenderCost()
}
}
}
+
cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
setDebugText(llformat("%d", cost));