diff options
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r-- | indra/newview/llvoavatar.cpp | 243 |
1 files changed, 168 insertions, 75 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 80c6805ead..eab5206828 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -44,6 +44,7 @@ #include "llavatarnamecache.h" #include "llavatarpropertiesprocessor.h" #include "llavatarrendernotifier.h" +#include "llcontrolavatar.h" #include "llexperiencecache.h" #include "llphysicsmotion.h" #include "llviewercontrol.h" @@ -663,7 +664,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastUpdateRequestCOFVersion(-1), mLastUpdateReceivedCOFVersion(-1), mCachedMuteListUpdateTime(0), - mCachedInMuteList(false) + mCachedInMuteList(false), + mIsControlAvatar(false), + mEnableDefaultMotions(true) { LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; @@ -718,6 +721,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mCurrentGesticulationLevel = 0; + mRuthTimer.reset(); mRuthDebugTimer.reset(); mDebugExistenceTimer.reset(); @@ -1222,8 +1226,6 @@ const LLVector3 LLVOAvatar::getRenderPosition() const { return getPosition() * mDrawable->getParent()->getRenderMatrix(); } - - } void LLVOAvatar::updateDrawable(BOOL force_damped) @@ -1240,6 +1242,10 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector) void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { + if (mDrawable.isNull()) + { + return; + } if (isImpostor() && !needsImpostorUpdate()) { LLVector3 delta = getRenderPosition() - @@ -1404,13 +1410,29 @@ void LLVOAvatar::renderCollisionVolumes() static F32 sphere_scale = 1.0f; static F32 center_dot_scale = 0.05f; - static LLVector3 CV_COLOR_OCCLUDED(0.0f, 0.0f, 1.0f); - static LLVector3 CV_COLOR_VISIBLE(0.5f, 0.5f, 1.0f); - static LLVector3 DOT_COLOR_OCCLUDED(1.0f, 1.0f, 1.0f); - static LLVector3 DOT_COLOR_VISIBLE(1.0f, 1.0f, 1.0f); + static LLVector3 BLUE(0.0f, 0.0f, 1.0f); + static LLVector3 PASTEL_BLUE(0.5f, 0.5f, 1.0f); + static LLVector3 RED(1.0f, 0.0f, 0.0f); + static LLVector3 PASTEL_RED(1.0f, 0.5f, 0.5f); + static LLVector3 WHITE(1.0f, 1.0f, 1.0f); + - render_sphere_and_line(begin_pos, end_pos, sphere_scale, CV_COLOR_OCCLUDED, CV_COLOR_VISIBLE); - render_sphere_and_line(begin_pos, end_pos, center_dot_scale, DOT_COLOR_OCCLUDED, DOT_COLOR_VISIBLE); + LLVector3 cv_color_occluded; + LLVector3 cv_color_visible; + LLVector3 dot_color_occluded(WHITE); + LLVector3 dot_color_visible(WHITE); + if (isControlAvatar()) + { + cv_color_occluded = RED; + cv_color_visible = PASTEL_RED; + } + else + { + cv_color_occluded = BLUE; + cv_color_visible = PASTEL_BLUE; + } + render_sphere_and_line(begin_pos, end_pos, sphere_scale, cv_color_occluded, cv_color_visible); + render_sphere_and_line(begin_pos, end_pos, center_dot_scale, dot_color_occluded, dot_color_visible); gGL.popMatrix(); } @@ -1422,9 +1444,6 @@ void LLVOAvatar::renderCollisionVolumes() mNameText->lineSegmentIntersect(unused, unused, unused, TRUE); } - - mDebugText.clear(); - addDebugText(ostr.str()); } void LLVOAvatar::renderBones() @@ -1595,6 +1614,11 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& return FALSE; } + if (isControlAvatar()) + { + return FALSE; + } + if (lineSegmentBoundingBox(start, end)) { for (S32 i = 0; i < mNumCollisionVolumes; ++i) @@ -1680,6 +1704,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& return FALSE; } +// virtual LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, @@ -1796,7 +1821,11 @@ void LLVOAvatar::buildCharacter() mAahMorph = getVisualParam( "Express_Open_Mouth" ); } - startDefaultMotions(); + // Currently disabled for control avatars (animated objects), enabled for all others. + if (mEnableDefaultMotions) + { + startDefaultMotions(); + } //------------------------------------------------------------------------- // restart any currently active motions @@ -1942,6 +1971,8 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) //----------------------------------------------------------------------------- void LLVOAvatar::releaseMeshData() { + // AXON what should we be doing here for control avs? Why are + // dummies treated differently in the first place? if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || mIsDummy) { return; @@ -1962,15 +1993,15 @@ void LLVOAvatar::releaseMeshData() LLFace* facep = mDrawable->getFace(0); if (facep) { - facep->setSize(0, 0); - for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) - { - facep = mDrawable->getFace(i); + facep->setSize(0, 0); + for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) + { + facep = mDrawable->getFace(i); if (facep) { - facep->setSize(0, 0); - } - } + facep->setSize(0, 0); + } + } } } @@ -1994,6 +2025,10 @@ void LLVOAvatar::releaseMeshData() void LLVOAvatar::restoreMeshData() { llassert(!isSelf()); + if (mDrawable.isNull()) + { + return; + } //LL_INFOS() << "Restoring" << LL_ENDL; mMeshValid = TRUE; @@ -2571,13 +2606,16 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } } - mDrawable->movePartition(); - - //force a move if sitting on an active object - if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) - { - gPipeline.markMoved(mDrawable, TRUE); - } + if (mDrawable.notNull()) + { + mDrawable->movePartition(); + + //force a move if sitting on an active object + if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) + { + gPipeline.markMoved(mDrawable, TRUE); + } + } } void LLVOAvatar::idleUpdateAppearanceAnimation() @@ -2738,7 +2776,8 @@ void LLVOAvatar::idleUpdateLoadingEffect() LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | LLPartData::LL_PART_TARGET_POS_MASK ); - if (!isTooComplex()) // do not generate particles for overly-complex avatars + // AXON skip cloud effects for dummy avs as well + if (!mIsDummy && !isTooComplex()) // do not generate particles for overly-complex avatars { setParticleSource(particle_parameters, getID()); } @@ -3338,8 +3377,7 @@ bool LLVOAvatar::isInMuteList() void LLVOAvatar::updateDebugText() { - // clear debug text - mDebugText.clear(); + // Leave mDebugText uncleared here, in case a derived class has added some state first if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) { @@ -3406,6 +3444,7 @@ void LLVOAvatar::updateDebugText() addDebugText(mBakedTextureDebugText); } + // Develop -> Avatar -> Animation Info if (LLVOAvatar::sShowAnimationDebug) { for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); @@ -3415,8 +3454,27 @@ void LLVOAvatar::updateDebugText() if (motionp->getMinPixelArea() < getPixelArea()) { std::string output; - if (motionp->getName().empty()) + std::string motion_name = motionp->getName(); + if (motion_name.empty()) { + if (isControlAvatar()) + { + LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this); + // Try to get name from inventory of associated object + LLVOVolume *volp = control_av->mRootVolp; + if (volp) + { + volp->requestInventory(); // AXON should be a no-op if already requested or fetched? + LLViewerInventoryItem* item = volp->getInventoryItemByAsset(motionp->getID()); + if (item) + { + motion_name = item->getName(); + } + } + } + } + if (motion_name.empty()) + { output = llformat("%s - %d", gAgent.isGodlikeWithoutAdminMenuFakery() ? motionp->getID().asString().c_str() : @@ -3426,8 +3484,8 @@ void LLVOAvatar::updateDebugText() else { output = llformat("%s - %d", - motionp->getName().c_str(), - (U32)motionp->getPriority()); + motion_name.c_str(), + (U32)motionp->getPriority()); } addDebugText(output); } @@ -3443,8 +3501,7 @@ void LLVOAvatar::updateDebugText() { setDebugText(mDebugText); } - mDebugText.clear(); - + mDebugText.clear(); } //------------------------------------------------------------------------ @@ -3474,7 +3531,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) //-------------------------------------------------------------------- bool visually_muted = isVisuallyMuted(); - if (visible && (!isSelf() || visually_muted) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) + // AXON FIXME this expression is a crawling horror + if (mDrawable.notNull() && visible && (!isSelf() || visually_muted) && + !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; @@ -3530,7 +3589,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } // change animation time quanta based on avatar render load - if (!isSelf() && !mIsDummy) + // AXON how should control avs be handled here? + bool is_pure_dummy = mIsDummy && !isControlAvatar(); + if (!isSelf() && !is_pure_dummy) { F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f); F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f); @@ -3652,7 +3713,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) //-------------------------------------------------------------------- // Propagate viewer object rotation to root of avatar //-------------------------------------------------------------------- - if (!isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) + // AXON - also skip for control avatars + if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) { LLQuaternion iQ; LLVector3 upDir( 0.0f, 0.0f, 1.0f ); @@ -4041,7 +4103,7 @@ void LLVOAvatar::updateVisibility() if (mIsDummy) { - visible = TRUE; + visible = FALSE; } else if (mDrawable.isNull()) { @@ -4190,6 +4252,11 @@ U32 LLVOAvatar::renderSkinned() return num_indices; } + if (mDrawable.isNull()) + { + return num_indices; + } + LLFace* face = mDrawable->getFace(0); bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); @@ -4352,11 +4419,12 @@ U32 LLVOAvatar::renderSkinned() } BOOL first_pass = TRUE; + bool is_pure_dummy = mIsDummy && !isControlAvatar(); if (!LLDrawPoolAvatar::sSkipOpaque) { if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { - if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) + if (isTextureVisible(TEX_HEAD_BAKED) || is_pure_dummy) { LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); if (head_mesh) @@ -4366,7 +4434,7 @@ U32 LLVOAvatar::renderSkinned() first_pass = FALSE; } } - if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) + if (isTextureVisible(TEX_UPPER_BAKED) || is_pure_dummy) { LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); if (upper_mesh) @@ -4376,7 +4444,7 @@ U32 LLVOAvatar::renderSkinned() first_pass = FALSE; } - if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) + if (isTextureVisible(TEX_LOWER_BAKED) || is_pure_dummy) { LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); if (lower_mesh) @@ -4433,18 +4501,15 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } first_pass = FALSE; } - // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) - // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if ( (getImage(TEX_HAIR_BAKED, 0) && getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE) - || LLDrawPoolAlpha::sShowDebugAlpha) - { - LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); - if (hair_mesh) - { - num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } + if (isTextureVisible(TEX_HAIR_BAKED)) + { + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + if (hair_mesh) + { + num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } if (LLPipeline::sImpostorRender) { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); @@ -4484,7 +4549,9 @@ U32 LLVOAvatar::renderRigid() gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); } - if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy) + bool is_pure_dummy = mIsDummy && !isControlAvatar(); + + if (isTextureVisible(TEX_EYES_BAKED) || is_pure_dummy) { LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); @@ -5034,7 +5101,10 @@ void LLVOAvatar::processAnimationStateChanges() else if (mInAir && !mIsSitting) { stopMotion(ANIM_AGENT_WALK_ADJUST); - startMotion(ANIM_AGENT_FLY_ADJUST); + if (mEnableDefaultMotions) + { + startMotion(ANIM_AGENT_FLY_ADJUST); + } } else { @@ -5044,13 +5114,19 @@ void LLVOAvatar::processAnimationStateChanges() if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) ) { - startMotion(ANIM_AGENT_TARGET); + if (mEnableDefaultMotions) + { + startMotion(ANIM_AGENT_TARGET); + } stopMotion(ANIM_AGENT_BODY_NOISE); } else { stopMotion(ANIM_AGENT_TARGET); - startMotion(ANIM_AGENT_BODY_NOISE); + if (mEnableDefaultMotions) + { + startMotion(ANIM_AGENT_BODY_NOISE); + } } // clear all current animations @@ -5521,14 +5597,13 @@ void LLVOAvatar::rebuildAttachmentOverrides() //----------------------------------------------------------------------------- void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) { - LLVOAvatar *av = vo->getAvatarAncestor(); - if (!av || (av != this)) - { + if (vo->getAvatar() != this) + { LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; return; - } + } - LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname()); + LLScopedContextString str("addAttachmentOverridesForObject " + vo->getAvatar()->getFullname()); // Process all children LLViewerObject::const_child_list_t& children = vo->getChildren(); @@ -5554,7 +5629,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); - if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) + if ( vobj && vobj->isMesh() && pSkinData ) { const int bindCnt = pSkinData->mAlternateBindMatrix.size(); const int jointCnt = pSkinData->mJointNames.size(); @@ -5736,14 +5811,15 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const } //----------------------------------------------------------------------------- -// resetJointsOnDetach +// removeAttachmentOverridesForObject //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo) +// AXON handle NPC case +void LLVOAvatar::removeAttachmentOverridesForObject(LLViewerObject *vo) { - LLVOAvatar *av = vo->getAvatarAncestor(); - if (!av || (av != this)) + if (vo->getAvatar() != this) { LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; + return; } // Process all children @@ -5752,21 +5828,22 @@ void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo) it != children.end(); ++it) { LLViewerObject *childp = *it; - resetJointsOnDetach(childp); + removeAttachmentOverridesForObject(childp); } // Process self. LLUUID mesh_id; if (getRiggedMeshID(vo,mesh_id)) { - resetJointsOnDetach(mesh_id); + removeAttachmentOverridesForObject(mesh_id); } } //----------------------------------------------------------------------------- -// resetJointsOnDetach +// removeAttachmentOverridesForObject //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id) +// AXON handle NPC case +void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id) { //Subsequent joints are relative to pelvis avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5844,6 +5921,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age LLVector3d z_vec(0.0f, 0.0f, 1.0f); LLVector3d p0_global, p1_global; + // AXON update for control avs? if (mIsDummy) { outNorm.setVec(z_vec); @@ -5873,6 +5951,7 @@ F32 LLVOAvatar::getTimeDilation() //----------------------------------------------------------------------------- F32 LLVOAvatar::getPixelArea() const { + // AXON update for control avatars if (mIsDummy) { return 100000.f; @@ -6288,7 +6367,7 @@ void LLVOAvatar::removeChild(LLViewerObject *childp) LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object) { - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getAttachmentState()); // This should never happen unless the server didn't process the attachment point // correctly, but putting this check in here to be safe. @@ -6483,7 +6562,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) LLUUID mesh_id; if (getRiggedMeshID(pVO, mesh_id)) { - resetJointsOnDetach(mesh_id); + removeAttachmentOverridesForObject(mesh_id); if ( gAgentCamera.cameraCustomizeAvatar() ) { gAgent.unpauseAnimation(); @@ -6644,7 +6723,10 @@ void LLVOAvatar::getOffObject() mRoot->setRotation(cur_rotation_world); mRoot->getXform()->update(); - startMotion(ANIM_AGENT_BODY_NOISE); + if (mEnableDefaultMotions) + { + startMotion(ANIM_AGENT_BODY_NOISE); + } if (isSelf()) { @@ -6804,6 +6886,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color) BOOL LLVOAvatar::isVisible() const { + // AXON should we flag control avs as invisible? return mDrawable.notNull() && (!mOrphaned || isSelf()) && (mDrawable->isVisible() || mIsDummy); @@ -6812,6 +6895,11 @@ BOOL LLVOAvatar::isVisible() const // Determine if we have enough avatar data to render bool LLVOAvatar::getIsCloud() const { + if (mIsDummy) + { + return false; + } + return ( ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault())// Do we have a shape? || ( !isTextureDefined(TEX_LOWER_BAKED) || !isTextureDefined(TEX_UPPER_BAKED) @@ -8776,6 +8864,11 @@ void LLVOAvatar::updateFreezeCounter(S32 counter) BOOL LLVOAvatar::updateLOD() { + if (mDrawable.isNull()) + { + return FALSE; + } + if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry()) { return TRUE; |