diff options
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r-- | indra/newview/llvoavatar.cpp | 637 |
1 files changed, 486 insertions, 151 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 0aee4a3398..4e5f868c48 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -207,6 +207,8 @@ enum ERenderName RENDER_NAME_FADE }; +#define JELLYDOLLS_SHOULD_IMPOSTOR + //----------------------------------------------------------------------------- // Callback data //----------------------------------------------------------------------------- @@ -657,6 +659,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mNeedsSkin(FALSE), mLastSkinTime(0.f), mUpdatePeriod(1), + mOverallAppearance(AOA_INVISIBLE), mVisualComplexityStale(true), mVisuallyMuteSetting(AV_RENDER_NORMALLY), mMutedAVColor(LLColor4::white /* used for "uninitialize" */), @@ -1319,6 +1322,11 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); + if (getOverallAppearance() != AOA_NORMAL) + { + // Jellydolls ignore attachments, etc, use only system avatar. + box_detail = 1; + } // FIXME the update_min_max function used below assumes there is a // known starting point, but in general there isn't. Ideally the @@ -2024,6 +2032,38 @@ void LLVOAvatar::resetVisualParams() } } +void LLVOAvatar::applyDefaultParams() +{ + // These are params from avs with newly created copies of shape, + // skin, hair, eyes, plus gender set as noted. Run arche_tool.py + // to get params from some other xml appearance dump. + std::map<S32, U8> male_params = { + {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} + }; + std::map<S32, U8> female_params = { + {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} + }; + std::map<S32, U8> *params = NULL; + if (getSex() == SEX_MALE) + params = &male_params; + else + params = &female_params; + + for( auto it = params->begin(); it != params->end(); ++it) + { + LLVisualParam* param = getVisualParam(it->first); + if( !param ) + { + // invalid id + break; + } + + U8 value = it->second; + F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); + param->setWeight(newWeight); + } +} + //----------------------------------------------------------------------------- // resetSkeleton() //----------------------------------------------------------------------------- @@ -2086,15 +2126,22 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) } // Reset tweakable params to preserved state - if (mLastProcessedAppearance) - { - bool slam_params = true; - applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); - } + if (getOverallAppearance() == AOA_NORMAL) + { + if (mLastProcessedAppearance) + { + bool slam_params = true; + applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); + } + } + else + { + applyDefaultParams(); + } updateVisualParams(); // Restore attachment pos overrides - updateAttachmentOverrides(); + updateAttachmentOverrides(); // Animations if (reset_animations) @@ -2729,6 +2776,9 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) BOOL visible = isVisible() || mNeedsAnimUpdate; // update attachments positions + // FIXME what does sUseImpostors do + // here? Shouldn't behavior be based on state of this avatar, + // rather than some piece of global state? if (detailed_update || !sUseImpostors) { LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE); @@ -2827,13 +2877,13 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (mDrawable.notNull()) { - mDrawable->movePartition(); + mDrawable->movePartition(); - //force a move if sitting on an active object - if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) - { - gPipeline.markMoved(mDrawable, TRUE); - } + //force a move if sitting on an active object + if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) + { + gPipeline.markMoved(mDrawable, TRUE); + } } } @@ -3562,8 +3612,13 @@ bool LLVOAvatar::isVisuallyMuted() muted = false; } else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) - { // Always want to see this AV as an impostor + { +#ifdef JELLYDOLLS_SHOULD_IMPOSTOR muted = true; + // Always want to see this AV as an impostor +#else + muted = false; +#endif } else if (isInMuteList()) { @@ -3578,7 +3633,7 @@ bool LLVOAvatar::isVisuallyMuted() return muted; } -bool LLVOAvatar::isInMuteList() +bool LLVOAvatar::isInMuteList() const { bool muted = false; F64 now = LLFrameTimer::getTotalSeconds(); @@ -3640,9 +3695,14 @@ void LLVOAvatar::updateAppearanceMessageDebugText() if (hover_offset[2] != 0.0) { debug_line += llformat(" hov_z: %.3f", hover_offset[2]); - debug_line += llformat(" %s", (isSitting() ? "S" : "T")); + debug_line += llformat(" %s", (isSitting() ? "S" : "T")); debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); } + if (mInAir) + { + debug_line += " A"; + + } LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); LLVector3 normal; @@ -3655,9 +3715,34 @@ void LLVOAvatar::updateAppearanceMessageDebugText() LLVector3 pelvis_pos = mPelvisp->getPosition(); debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); - S32 is_visible = (S32) isVisible(); - S32 is_m_visible = (S32) mVisible; - debug_line += llformat(" v %d/%d", is_visible, is_m_visible); + const LLVector3& scale = getScale(); + debug_line += llformat(" scale-z %.3f", scale[2]); + S32 is_visible = (S32) isVisible(); + S32 is_m_visible = (S32) mVisible; + debug_line += llformat(" v %d/%d", is_visible, is_m_visible); + + AvatarOverallAppearance aoa = getOverallAppearance(); + if (aoa == AOA_NORMAL) + { + debug_line += " N"; + } + else if (aoa == AOA_JELLYDOLL) + { + debug_line += " J"; + } + else + { + debug_line += " I"; + } + + if (mMeshValid) + { + debug_line += "m"; + } + else + { + debug_line += "-"; + } addDebugText(debug_line); } @@ -3699,13 +3784,13 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU void LLVOAvatar::updateAnimationDebugText() { - for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); - iter != mMotionController.getActiveMotions().end(); ++iter) + for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); + iter != mMotionController.getActiveMotions().end(); ++iter) + { + LLMotion* motionp = *iter; + if (motionp->getMinPixelArea() < getPixelArea()) { - LLMotion* motionp = *iter; - if (motionp->getMinPixelArea() < getPixelArea()) - { - std::string output; + std::string output; std::string motion_name = motionp->getName(); if (motion_name.empty()) { @@ -3722,73 +3807,74 @@ void LLVOAvatar::updateAnimationDebugText() } } if (motion_name.empty()) + { + std::string name; + if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) { - std::string name; - if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) + name = motionp->getID().asString(); + LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); + for (; anim_it != mAnimationSources.end(); ++anim_it) { - name = motionp->getID().asString(); - LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); - for (; anim_it != mAnimationSources.end(); ++anim_it) + if (anim_it->second == motionp->getID()) { - if (anim_it->second == motionp->getID()) + LLViewerObject* object = gObjectList.findObject(anim_it->first); + if (!object) + { + break; + } + if (object->isAvatar()) { - LLViewerObject* object = gObjectList.findObject(anim_it->first); - if (!object) + if (mMotionController.mIsSelf) { - break; + // Searching inventory by asset id is really long + // so just mark as inventory + // Also item is likely to be named by LLPreviewAnim + name += "(inventory)"; } - if (object->isAvatar()) + } + else + { + LLViewerInventoryItem* item = NULL; + if (!object->isInventoryDirty()) { - if (mMotionController.mIsSelf) - { - // Searching inventory by asset id is really long - // so just mark as inventory - // Also item is likely to be named by LLPreviewAnim - name += "(inventory)"; - } + item = object->getInventoryItemByAsset(motionp->getID()); + } + if (item) + { + name = item->getName(); + } + else if (object->isAttachment()) + { + name += "(att:" + getAttachmentItemName() + ")"; } else { - LLViewerInventoryItem* item = NULL; - if (!object->isInventoryDirty()) - { - item = object->getInventoryItemByAsset(motionp->getID()); - } - if (item) - { - name = item->getName(); - } - else if (object->isAttachment()) - { - name += "(" + getAttachmentItemName() + ")"; - } - else - { - // in-world object, name or content unknown - name += "(in-world)"; - } + // in-world object, name or content unknown + name += "(in-world)"; } - break; } + break; } } - else - { - name = LLUUID::null.asString(); - } - output = llformat("%s - %d", - name.c_str(), - (U32)motionp->getPriority()); } else { - output = llformat("%s - %d", - motion_name.c_str(), - (U32)motionp->getPriority()); + name = LLUUID::null.asString(); } - addDebugText(output); + motion_name = name; + } + std::string motion_tag = ""; + if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end()) + { + motion_tag = "*"; } + output = llformat("%s%s - %d", + motion_name.c_str(), + motion_tag.c_str(), + (U32)motionp->getPriority()); + addDebugText(output); } + } } void LLVOAvatar::updateDebugText() @@ -3925,7 +4011,7 @@ void LLVOAvatar::computeUpdatePeriod() && isVisible() && (!isSelf() || visually_muted) && !isUIAvatar() - && sUseImpostors + && sUseImpostors // FIXME && !mNeedsAnimUpdate && !sFreezeCounter) { @@ -3936,7 +4022,7 @@ void LLVOAvatar::computeUpdatePeriod() F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); if (visually_muted) - { // visually muted avatars update at 16 hz + { // visually muted avatars update at every 16 frames mUpdatePeriod = 16; } else if (! shouldImpostor() @@ -3973,7 +4059,6 @@ void LLVOAvatar::computeUpdatePeriod() { mUpdatePeriod = 1; } - } //------------------------------------------------------------------------ @@ -4244,7 +4329,33 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w if (!isSitting() && !was_sit_ground_constrained) { root_pos += LLVector3d(getHoverOffset()); - } + if (getOverallAppearance() == AOA_JELLYDOLL) + { + F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]); + root_pos[2] += offz; + // if (!isSelf() && !isControlAvatar()) + // { + // LL_DEBUGS("Avatar") << "av " << getFullname() + // << " frame " << LLFrameTimer::getFrameCount() + // << " root adjust offz " << offz + // << " scalez " << getScale()[VZ] + // << " bsz " << mBodySize.mV[VZ] + // << LL_ENDL; + // } + } + } + // if (!isSelf() && !isControlAvatar()) + // { + // LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance() + // << " frame " << LLFrameTimer::getFrameCount() + // << " scalez " << getScale()[VZ] + // << " bsz " << mBodySize.mV[VZ] + // << " root pos " << root_pos[2] + // << " curr rootz " << mRoot->getPosition()[2] + // << " pp-z " << mPelvisp->getPosition()[2] + // << " renderpos " << getRenderPosition() + // << LL_ENDL; + // } LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this); if (cav) @@ -4255,6 +4366,14 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w else { LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); + // if (!isSelf() && !isControlAvatar()) + // { + // LL_DEBUGS("Avatar") << "av " << getFullname() + // << " frame " << LLFrameTimer::getFrameCount() + // << " newPosition " << newPosition + // << " renderpos " << getRenderPosition() + // << LL_ENDL; + // } if (newPosition != mRoot->getXform()->getWorldPosition()) { mRoot->touch(); @@ -4356,6 +4475,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } //-------------------------------------------------------------------- + // Handle transitions between regular rendering, jellydoll, or invisible. + // Can trigger skeleton reset or animation changes + //-------------------------------------------------------------------- + updateOverallAppearance(); + + //-------------------------------------------------------------------- // change animation time quanta based on avatar render load //-------------------------------------------------------------------- // SL-763 the time step quantization does not currently work. @@ -4885,7 +5010,8 @@ U32 LLVOAvatar::renderSkinned() } if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { - if (isTextureVisible(TEX_HEAD_BAKED) || isUIAvatar()) + + if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) { LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); if (head_mesh) @@ -4895,7 +5021,7 @@ U32 LLVOAvatar::renderSkinned() first_pass = FALSE; } } - if (isTextureVisible(TEX_UPPER_BAKED) || isUIAvatar()) + if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) { LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); if (upper_mesh) @@ -4905,7 +5031,7 @@ U32 LLVOAvatar::renderSkinned() first_pass = FALSE; } - if (isTextureVisible(TEX_LOWER_BAKED) || isUIAvatar()) + if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) { LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); if (lower_mesh) @@ -4962,7 +5088,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } first_pass = FALSE; } - if (isTextureVisible(TEX_HAIR_BAKED)) + if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL)) { LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); if (hair_mesh) @@ -5010,7 +5136,7 @@ U32 LLVOAvatar::renderRigid() gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); } - if (isTextureVisible(TEX_EYES_BAKED) || isUIAvatar()) + if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) { LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); @@ -5639,8 +5765,8 @@ void LLVOAvatar::processAnimationStateChanges() stopMotion(ANIM_AGENT_TARGET); if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_BODY_NOISE); - } + startMotion(ANIM_AGENT_BODY_NOISE); + } } // clear all current animations @@ -5660,23 +5786,32 @@ void LLVOAvatar::processAnimationStateChanges() ++anim_it; } + // if jellydolled, shelve all playing animations + if (getOverallAppearance() != AOA_NORMAL) + { + mPlayingAnimations.clear(); + } + // start up all new anims - for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();) + if (getOverallAppearance() == AOA_NORMAL) { - AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); - - // signaled but not playing, or different sequence id, start motion - if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) + for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();) { - if (processSingleAnimationStateChange(anim_it->first, TRUE)) + AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); + + // signaled but not playing, or different sequence id, start motion + if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) { - mPlayingAnimations[anim_it->first] = anim_it->second; - ++anim_it; - continue; + if (processSingleAnimationStateChange(anim_it->first, TRUE)) + { + mPlayingAnimations[anim_it->first] = anim_it->second; + ++anim_it; + continue; + } } - } - ++anim_it; + ++anim_it; + } } // clear source information for animations which have been stopped @@ -6239,6 +6374,11 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL } LLScopedContextString str("addAttachmentOverridesForObject " + getFullname()); + + if (getOverallAppearance() != AOA_NORMAL) + { + return; + } LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL; dumpStack("AnimatedObjectsStack"); @@ -7658,9 +7798,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color) } // virtual +// Do rigged mesh attachments display with this av? bool LLVOAvatar::shouldRenderRigged() const { - return true; + if (getOverallAppearance() == AOA_NORMAL) + { + return true; + } + // TBD - render for AOA_JELLYDOLL? + return false; } // FIXME: We have an mVisible member, set in updateVisibility(), but this @@ -7941,12 +8087,14 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) } // did our loading state "change" from last call? - // runway - why are we updating every 30 calls even if nothing has changed? + // FIXME runway - why are we updating every 30 calls even if nothing has changed? + // This causes updateLOD() to run every 30 frames, among other things. const S32 UPDATE_RATE = 30; BOOL changed = ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call (!mFullyLoadedInitialized) || // if we've never been called before (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change + BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded); mPreviousFullyLoaded = mFullyLoaded; mFullyLoadedInitialized = TRUE; @@ -7957,7 +8105,12 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) // to know about outfit switching LLAvatarRenderNotifier::getInstance()->updateNotificationState(); } - + + if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor()) + { + // Fix for jellydoll initially invisible + mNeedsImpostorUpdate = TRUE; + } return changed; } @@ -8029,47 +8182,25 @@ void LLVOAvatar::updateMeshVisibility() bool bake_flag[BAKED_NUM_INDICES]; memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool)); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) + if (getOverallAppearance() == AOA_NORMAL) { - LLViewerJointAttachment* attachment = iter->second; - if (attachment) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + LLViewerJointAttachment* attachment = iter->second; + if (attachment) { - LLViewerObject *objectp = attachment_iter->get(); - if (objectp) - { - for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) - { - LLTextureEntry* tex_entry = objectp->getTE(face_index); - bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); - bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); - bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); - bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); - bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); - bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); - bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); - bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); - bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); - bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); - bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); - } - } - - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); - iter1 != child_list.end(); ++iter1) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLViewerObject* objectchild = *iter1; - if (objectchild) + LLViewerObject *objectp = attachment_iter->get(); + if (objectp) { - for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) + for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) { - LLTextureEntry* tex_entry = objectchild->getTE(face_index); + LLTextureEntry* tex_entry = objectp->getTE(face_index); bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); @@ -8083,6 +8214,31 @@ void LLVOAvatar::updateMeshVisibility() bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); } } + + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild) + { + for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectchild->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); + } + } + } } } } @@ -9013,7 +9169,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) mLastProcessedAppearance = contents; bool slam_params = false; - applyParsedAppearanceMessage(*contents, slam_params); + applyParsedAppearanceMessage(*contents, slam_params); + if (getOverallAppearance() != AOA_NORMAL) + { + resetSkeleton(false); + } } void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params) @@ -10096,11 +10256,12 @@ void LLVOAvatar::updateImpostors() for (std::vector<LLCharacter*>::iterator iter = instances_copy.begin(); iter != instances_copy.end(); ++iter) { + // FIXME state spaghetti! Can we just use shouldImpostor() here? LLVOAvatar* avatar = (LLVOAvatar*) *iter; - if (!avatar->isDead() && avatar->isVisible() - && ( - (avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate()) - ) + if (!avatar->isDead() + && avatar->isVisible() + && avatar->isImpostor() + && avatar->needsImpostorUpdate()) { avatar->calcMutedAVColor(); gPipeline.generateImpostor(avatar); @@ -10113,11 +10274,14 @@ void LLVOAvatar::updateImpostors() // virtual BOOL LLVOAvatar::isImpostor() { - return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; + // FIXME this doesn't seem to actually mean that the avatar is currently shown as an impostor, or should be. + // un-impostored avs have mUpdatePeriod 1. IMPOSTOR_PERIOD is 2. + return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)); } BOOL LLVOAvatar::shouldImpostor(const U32 rank_factor) const { + // FIXME sUseImpostors question return (!isSelf() && sUseImpostors && mVisibilityRank > (sMaxNonImpostors * rank_factor)); } @@ -10573,6 +10737,172 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set)); } + +void LLVOAvatar::setOverallAppearanceNormal() +{ + if (isControlAvatar()) + return; + + LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); + resetSkeleton(false); + getJoint("mPelvis")->setPosition(pelvis_pos); + + for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it) + { + bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); + LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; + if (!is_playing) + { + // Anim was not requested for this av by sim, but may be playing locally + stopMotion(*it); + } + } + mJellyAnims.clear(); + + processAnimationStateChanges(); +} + +void LLVOAvatar::setOverallAppearanceJellyDoll() +{ + if (isControlAvatar()) + return; + + // stop current animations + { + for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin(); + anim_it != mPlayingAnimations.end(); + ++anim_it) + { + { + stopMotion(anim_it->first, TRUE); + } + } + } + processAnimationStateChanges(); + + // Start any needed anims for jellydoll + updateOverallAppearanceAnimations(); + + LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); + resetSkeleton(false); + getJoint("mPelvis")->setPosition(pelvis_pos); + +} + +void LLVOAvatar::setOverallAppearanceInvisible() +{ +} + +void LLVOAvatar::updateOverallAppearance() +{ + AvatarOverallAppearance new_overall = getOverallAppearance(); + if (new_overall != mOverallAppearance) + { + switch (new_overall) + { + case AOA_NORMAL: + setOverallAppearanceNormal(); + break; + case AOA_JELLYDOLL: + setOverallAppearanceJellyDoll(); + break; + case AOA_INVISIBLE: + setOverallAppearanceInvisible(); + break; + } + mOverallAppearance = new_overall; + if (!isSelf()) + { + mNeedsImpostorUpdate = TRUE; + } + updateMeshVisibility(); + } + + // This needs to be done even if overall appearance has not + // changed, since sit/stand status can be different. + updateOverallAppearanceAnimations(); +} + +void LLVOAvatar::updateOverallAppearanceAnimations() +{ + if (isControlAvatar()) + return; + + if (getOverallAppearance() == AOA_JELLYDOLL) + { + LLUUID motion_id; + if (isSitting() && getParent()) // sitting on object + { + motion_id = ANIM_AGENT_SIT_FEMALE; + } + else if (isSitting()) // sitting on ground + { + motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED; + } + else // standing + { + motion_id = ANIM_AGENT_STAND; + } + if (mJellyAnims.find(motion_id) == mJellyAnims.end()) + { + for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it) + { + bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); + LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; + if (!is_playing) + { + // Anim was not requested for this av by sim, but may be playing locally + stopMotion(*it, TRUE); + } + } + mJellyAnims.clear(); + + startMotion(motion_id); + mJellyAnims.insert(motion_id); + + processAnimationStateChanges(); + } + } +} + +// Based on isVisuallyMuted(), but has 3 possible results. +LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const +{ + AvatarOverallAppearance result = AOA_NORMAL; + + // Priority order (highest priority first) + // * own avatar is always drawn normally + // * if on the "always draw normally" list, draw them normally + // * if on the "always visually mute" list, show as jellydoll + // * if explicitly muted (blocked), show as invisible + // * check against the render cost and attachment limits - if too complex, show as jellydoll + if (isSelf()) + { + result = AOA_NORMAL; + } + else // !isSelf() + { + if (isInMuteList()) + { + result = AOA_INVISIBLE; + } + else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER) + { + result = AOA_NORMAL; + } + else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) + { // Always want to see this AV as an impostor + result = AOA_JELLYDOLL; + } + else if (isTooComplex()) + { + result = AOA_JELLYDOLL; + } + } + + return result; +} + void LLVOAvatar::calcMutedAVColor() { LLColor4 new_color(mMutedAVColor); @@ -10582,8 +10912,8 @@ void LLVOAvatar::calcMutedAVColor() if (getVisualMuteSettings() == AV_DO_NOT_RENDER) { // explicitly not-rendered avatars are light grey - new_color = LLColor4::grey3; - change_msg = " not rendered: color is grey3"; + new_color = LLColor4::grey4; + change_msg = " not rendered: color is grey4"; } else if (LLMuteList::getInstance()->isMuted(av_id)) // the user blocked them { @@ -10596,26 +10926,31 @@ void LLVOAvatar::calcMutedAVColor() new_color = LLColor4::white; change_msg = " simple imposter "; } +#ifdef COLORIZE_JELLYDOLLS else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 ) - { + { // select a color based on the first byte of the agents uuid so any muted agent is always the same color F32 color_value = (F32) (av_id.mData[0]); - F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f + F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f - // Array of colors. These are arranged so only one RGB color changes between each step, + // Array of colors. These are arranged so only one RGB color changes between each step, // and it loops back to red so there is an even distribution. It is not a heat map - const S32 NUM_SPECTRUM_COLORS = 7; + const S32 NUM_SPECTRUM_COLORS = 7; static LLColor4 * spectrum_color[NUM_SPECTRUM_COLORS] = { &LLColor4::red, &LLColor4::magenta, &LLColor4::blue, &LLColor4::cyan, &LLColor4::green, &LLColor4::yellow, &LLColor4::red }; - - spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1); // Scale to range of number of colors - S32 spectrum_index_1 = floor(spectrum); // Desired color will be after this index - S32 spectrum_index_2 = spectrum_index_1 + 1; // and before this index (inclusive) + + spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1); // Scale to range of number of colors + S32 spectrum_index_1 = floor(spectrum); // Desired color will be after this index + S32 spectrum_index_2 = spectrum_index_1 + 1; // and before this index (inclusive) F32 fractBetween = spectrum - (F32)(spectrum_index_1); // distance between the two indexes (0-1) - - new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween); - new_color.normalize(); - new_color *= 0.28f; // Tone it down + new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween); + new_color.normalize(); + new_color *= 0.28f; // Tone it down + } +#endif + else + { + new_color = LLColor4::grey4; change_msg = " over limit color "; } |