diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index d963ab0205..b4d0d8869f 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -1753,7 +1753,7 @@ void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info) } mJointAliasMap[*i] = bone_name; } - + LLAvatarBoneInfo::child_list_t::const_iterator iter; for (iter = bone_info->mChildList.begin(); iter != bone_info->mChildList.end(); ++iter) { @@ -1768,13 +1768,34 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases { LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; - for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin(); iter != sAvatarSkeletonInfo->mBoneInfoList.end(); ++iter) + for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin(); + iter != sAvatarSkeletonInfo->mBoneInfoList.end(); + ++iter) { //LLAvatarBoneInfo *bone_info = *iter; makeJointAliases( *iter ); } + + LLAvatarXmlInfo::attachment_info_list_t::iterator attach_iter; + for (attach_iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); + attach_iter != sAvatarXmlInfo->mAttachmentInfoList.end(); + ++attach_iter) + { + LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *attach_iter; + std::string bone_name = info->mName; + + // Also accept the name with spaces substituted with + // underscores. This gives a mechanism for referencing such joints + // in daes, which don't allow spaces. + std::string sub_space_to_underscore = bone_name; + LLStringUtil::replaceChar(sub_space_to_underscore, ' ', '_'); + if (sub_space_to_underscore != bone_name) + { + mJointAliasMap[sub_space_to_underscore] = bone_name; + } + } } - + return mJointAliasMap; } diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index c83792ef18..ae7352b528 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -136,7 +136,7 @@ LLMotionController::LLMotionController() mLastTime(0.0f), mHasRunOnce(FALSE), mPaused(FALSE), - mPauseTime(0.f), + mPausedFrame(0), mTimeStep(0.f), mTimeStepCount(0), mLastInterp(0.f), @@ -1133,6 +1133,7 @@ void LLMotionController::pauseAllMotions() { //LL_INFOS() << "Pausing animations..." << LL_ENDL; mPaused = TRUE; + mPausedFrame = LLFrameTimer::getFrameCount(); } } diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index dc3a747491..f03a8d1834 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -148,6 +148,7 @@ public: void pauseAllMotions(); void unpauseAllMotions(); BOOL isPaused() const { return mPaused; } + S32 getPausedFrame() const { return mPausedFrame; } void setTimeStep(F32 step); F32 getTimeStep() const { return mTimeStep; } @@ -225,7 +226,7 @@ protected: F32 mLastTime; BOOL mHasRunOnce; BOOL mPaused; - F32 mPauseTime; + S32 mPausedFrame; F32 mTimeStep; S32 mTimeStepCount; F32 mLastInterp; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e2835879af..18997db270 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3781,6 +3781,17 @@ Value 0 + AnimatedObjectsAllowLeftClick + + Comment + Allow left-click interaction with animated objects. Uncertain how much performance impact this will have. + Persist + 1 + Type + Boolean + Value + 0 + DebugAvatarAppearanceMessage Comment diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 0f4898e8d3..7270cad0da 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -113,7 +113,7 @@ void LLControlAvatar::setGlobalScale(F32 scale) { F32 adjust_scale = scale/mGlobalScale; LL_INFOS() << "scale " << scale << " adjustment " << adjust_scale << LL_ENDL; - // AXON - should we be scaling from the pelvis or the root? + // should we be scaling from the pelvis or the root? recursiveScaleJoint(mPelvisp,adjust_scale); mGlobalScale = scale; } @@ -167,7 +167,10 @@ void LLControlAvatar::updateVolumeGeom() matchVolumeTransform(); - // AXON testing scale + // Initial exploration of allowing scaling skeleton to match root + // prim bounding box. If enabled, would probably be controlled by + // an additional checkbox and default to off. Not enabled for + // initial release. // What should the scale be? What we really want is the ratio // between the scale at which the object was originally designed @@ -239,6 +242,7 @@ void LLControlAvatar::updateDebugText() std::string lod_string; S32 total_tris = 0; S32 total_verts = 0; + S32 est_tris = 0; for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) { @@ -246,6 +250,7 @@ void LLControlAvatar::updateDebugText() S32 verts = 0; total_tris += volp->getTriangleCount(&verts); total_verts += verts; + est_tris += volp->getEstTrianglesMax(); lod_string += llformat("%d",volp->getLOD()); if (volp && volp->mDrawable) { @@ -282,8 +287,9 @@ void LLControlAvatar::updateDebugText() addDebugText(llformat("CAV obj %d anim %d active %s impost %d", total_linkset_count, animated_volume_count, active_string.c_str(), (S32) isImpostor())); addDebugText(llformat("types %s lods %s", type_string.c_str(), lod_string.c_str())); - addDebugText(llformat("tris %d verts %d", total_tris, total_verts)); + addDebugText(llformat("tris %d (est %d), verts %d", total_tris, est_tris, total_verts)); addDebugText(llformat("pxarea %s", LLStringOps::getReadableNumber(getPixelArea()).c_str())); +#if 0 std::string region_name = "no region"; if (mRootVolp->getRegion()) { @@ -297,10 +303,7 @@ void LLControlAvatar::updateDebugText() addDebugText(llformat("region %x %s skel %x %s", mRootVolp->getRegion(), region_name.c_str(), getRegion(), skel_region_name.c_str())); - //addDebugText(llformat("anim time %.1f (step %f factor %f)", - // mMotionController.getAnimTime(), - // mMotionController.getTimeStep(), - // mMotionController.getTimeFactor())); +#endif } LLVOAvatar::updateDebugText(); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index f74164aea6..1ec8d97f36 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -140,7 +140,7 @@ LLViewerTexture *LLDrawPool::getDebugTexture() return NULL; } -//virtual +//virtuals void LLDrawPool::beginRenderPass( S32 pass ) { } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 2c7603abca..3a65486024 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -116,6 +116,32 @@ LLDrawPoolAvatar::LLDrawPoolAvatar() : { } +LLDrawPoolAvatar::~LLDrawPoolAvatar() +{ + if (!isDead()) + { + LL_WARNS() << "Destroying avatar drawpool that still contains faces" << LL_ENDL; + } +} + +// virtual +BOOL LLDrawPoolAvatar::isDead() +{ + if (!LLFacePool::isDead()) + { + return FALSE; + } + + for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) + { + if (mRiggedFace[i].size() > 0) + { + return FALSE; + } + } + return TRUE; +} + //----------------------------------------------------------------------------- // instancePool() //----------------------------------------------------------------------------- @@ -2345,11 +2371,16 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) { + llassert (facep->isState(LLFace::RIGGED)); + llassert(getType() == LLDrawPool::POOL_AVATAR); + if (facep->getPool() && facep->getPool() != this) + { + LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL; + } if (type >= NUM_RIGGED_PASSES) { LL_ERRS() << "Invalid rigged face type." << LL_ENDL; } - if (facep->getRiggedIndex(type) != -1) { LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL; @@ -2362,6 +2393,12 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) { + llassert (facep->isState(LLFace::RIGGED)); + llassert(getType() == LLDrawPool::POOL_AVATAR); + if (facep->getPool() != this) + { + LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL; + } facep->setPool(NULL); for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 2002fe3451..be1a64a532 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -60,6 +60,8 @@ public: virtual S32 getVertexShaderLevel() const; LLDrawPoolAvatar(); + ~LLDrawPoolAvatar(); + /*virtual*/ BOOL isDead(); static LLMatrix4& getModelView(); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index a9432c56fc..b4654b73fe 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -793,7 +793,7 @@ void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAccep mDrop = drop; if (mDrop) { - // don't allow drag and drop onto transparent objects + // don't allow drag and drop onto rigged or transparent objects pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE)); } else diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index c9444ff209..29c1035720 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -120,9 +120,12 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mMouseOutsideSlop = FALSE; mMouseDownX = x; mMouseDownY = y; - + LLTimer pick_timer; + // AXON experimental feature + BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); //left mouse down always picks transparent (but see handleMouseUp) - mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE); + mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged); + LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL; mPick.mKeyMask = mask; mMouseButtonDown = true; @@ -137,7 +140,10 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask) { // don't pick transparent so users can't "pay" transparent objects - mPick = gViewerWindow->pickImmediate(x, y, /*BOOL pick_transparent*/ FALSE, /*BOOL pick_rigged*/ TRUE, /*BOOL pick_particle*/ TRUE); + mPick = gViewerWindow->pickImmediate(x, y, + /*BOOL pick_transparent*/ FALSE, + /*BOOL pick_rigged*/ TRUE, + /*BOOL pick_particle*/ TRUE); mPick.mKeyMask = mask; // claim not handled so UI focus stays same @@ -579,7 +585,9 @@ void LLToolPie::selectionPropertiesReceived() BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) { - mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE, FALSE); + // AXON experimental feature + BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); + mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged); LLViewerObject *parent = NULL; LLViewerObject *object = mHoverPick.getObject(); // [RLVa:KB] - Checked: RLVa-1.1.0 @@ -640,7 +648,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) else { // perform a separate pick that detects transparent objects since they respond to 1-click actions - LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE); + LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged); LLViewerObject* click_action_object = click_action_pick.getObject(); @@ -732,6 +740,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) LLPickInfo savedPick = mPick; mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, FALSE /* ignore transparent */, + FALSE /* ignore rigged */, FALSE /* ignore particles */); // if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick @@ -835,6 +844,7 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask) LLPickInfo savedPick = mPick; mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, FALSE /* ignore transparent */, + FALSE /* ignore rigged */, FALSE /* ignore particles */); if(mPick.mPickType == LLPickInfo::PICK_OBJECT) diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index d60cb8ee82..3f50dd9a84 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -68,7 +68,9 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite ) BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask) { // do immediate pick query - mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE); + // AXON experimental feature + BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); + mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged); // Pass mousedown to agent LLTool::handleMouseDown(x, y, mask); diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp index 71dc8001d4..d655dd881e 100644 --- a/indra/newview/lltoolselectrect.cpp +++ b/indra/newview/lltoolselectrect.cpp @@ -71,7 +71,9 @@ void dialog_refresh_all(void); BOOL LLToolSelectRect::handleMouseDown(S32 x, S32 y, MASK mask) { - handlePick(gViewerWindow->pickImmediate(x, y, TRUE, FALSE)); + // AXON experimental feature + BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); + handlePick(gViewerWindow->pickImmediate(x, y, TRUE /* pick_transparent */, pick_rigged)); LLTool::handleMouseDown(x, y, mask); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c1ad828102..91d1a906dc 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6676,6 +6676,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data) return; } + volp->updateControlAvatar(); LLControlAvatar *avatarp = volp->getControlAvatar(); if (!avatarp) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cdd8b09f7d..8c48290d4a 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3018,6 +3018,34 @@ LLControlAvatar *LLViewerObject::getControlAvatar() const return getRootEdit()->mControlAvatar.get(); } +void LLViewerObject::updateControlAvatar() +{ + LLViewerObject *root = getRootEdit(); + if (root->isAnimatedObject() && !root->getControlAvatar()) + { + bool any_mesh = root->isMesh(); + LLViewerObject::const_child_list_t& child_list = root->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + const LLViewerObject* child = *iter; + any_mesh = any_mesh || child->isMesh(); + } + if (any_mesh) + { + std::string vobj_name = llformat("Vol%u", (U32) root); + LL_DEBUGS("AnimatedObjects") << vobj_name << " calling linkControlAvatar()" << LL_ENDL; + root->linkControlAvatar(); + } + } + if (!root->isAnimatedObject() && root->getControlAvatar()) + { + std::string vobj_name = llformat("Vol%u", (U32) root); + LL_DEBUGS("AnimatedObjects") << vobj_name << " calling unlinkControlAvatar()" << LL_ENDL; + root->unlinkControlAvatar(); + } +} + void LLViewerObject::linkControlAvatar() { if (!getControlAvatar() && isRootEdit()) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index d2be327634..fdd95d9df7 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -720,6 +720,8 @@ public: void linkControlAvatar(); // Remove any reference to control av for this prim void unlinkControlAvatar(); + // Link or unlink as needed + void updateControlAvatar(); virtual bool isAnimatedObject() const; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f91b851482..7f940aa3e6 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1233,7 +1233,9 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi if (prim_media_dnd_enabled) { - LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/, FALSE ); + LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, + TRUE /* pick_transparent */, + FALSE /* pick_rigged */); LLUUID object_id = pick_info.getObjectID(); S32 object_face = pick_info.mObjectFace; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3f0094a1dd..3c3d32b94e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4020,7 +4020,10 @@ void LLVOAvatar::updateDebugText() LLVOVolume *volp = control_av->mRootVolp; if (volp) { - volp->requestInventory(); + if (volp->getInventorySerial()<=0) + { + volp->requestInventory(); + } LLViewerInventoryItem* item = volp->getInventoryItemByAsset(motionp->getID()); if (item) { @@ -4525,7 +4528,6 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition()); root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER); - // AXON need to review mInAir calcs for animated objects, if the value even matters. LLVector3 normal; resolveHeightGlobal(root_pos, ground_under_pelvis, normal); F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]); @@ -4574,9 +4576,8 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w //-------------------------------------------------------------------- if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) { - // AXON - should we always skip for control avatars? - // Rotation fixups for avatars in motion, some may be - // relevant. + // Rotation fixups for avatars in motion. + // Skip for animated objects. updateOrientation(agent, speed, delta_time); } } @@ -6823,8 +6824,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) + if (isUIAvatar()) { outNorm.setVec(z_vec); out_pos_agent = in_pos_agent; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e178cc3921..efff754d5b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1452,16 +1452,12 @@ BOOL LLVOVolume::calcLOD() if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT) && mDrawable->getFace(0)) { - if (isRootEdit() && getChildren().size()>0) + if (isRootEdit()) { S32 total_tris = recursiveGetTriangleCount(); - setDebugText(llformat("TRIS %d TOTAL %d", getTriangleCount(), total_tris)); + S32 est_max_tris = recursiveGetEstTrianglesMax(); + setDebugText(llformat("TRIS SHOWN %d EST %d", total_tris, est_max_tris)); } - else - { - setDebugText(llformat("TRIS %d", getTriangleCount())); - } - } // FIRE-20191 / STORM-2139 Render Metadata->LOD Info is broken on all "recent" viewer versions //if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && @@ -3544,12 +3540,11 @@ U32 LLVOVolume::getExtendedMeshFlags() const void LLVOVolume::onSetExtendedMeshFlags(U32 flags) { - // AXON - the check against isAnySelected() is "empirically - // derived": doing rebuildGeom() while in selection trashes the - // graphics state of animated objects. Skipping this update is OK - // because we get another one on deselect. - if (!getRootEdit()->isAnySelected() && mDrawable.notNull()) + // The isAnySelected() check was needed at one point to prevent + // graphics problems. These are now believed to be fixed so the + // check has been disabled. + if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull()) { // Need to trigger rebuildGeom(), which is where control avatars get created/removed getRootEdit()->recursiveMarkForUpdate(TRUE); @@ -4646,6 +4641,21 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons { copyVolumeFaces(volume); } + else + { +#if 1 + bool is_paused = avatar && avatar->areAnimationsPaused(); + if (is_paused) + { + S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); + if (frames_paused > 2) + { + return; + } + } +#endif + } + //build matrix palette static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; @@ -5343,38 +5353,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying); - if (vobj->isAnimatedObject()) + vobj->updateControlAvatar(); + if (vobj->getControlAvatar()) { - if (!vobj->getControlAvatar()) - { - F32 tri_count = vobj->getRootEdit()->recursiveGetEstTrianglesMax(); - if (tri_count <= 0.f) - { - LL_DEBUGS("AnimatedObjects") << vobj_name << " not calling linkControlAvatar(), because no tris" << LL_ENDL; - } - else - { - LL_DEBUGS("AnimatedObjects") << vobj_name << " calling linkControlAvatar()" << LL_ENDL; - vobj->linkControlAvatar(); - } - } - if (vobj->getControlAvatar()) - { - rigged_av = vobj->getControlAvatar(); - rigged_av->rebuildAttachmentOverrides(); - } + rigged_av = vobj->getControlAvatar(); + rigged_av->rebuildAttachmentOverrides(); } - else - { - // Not animated but has a control avatar - probably - // the checkbox has changed since the last rebuild. - if (vobj->getControlAvatar()) - { - LL_DEBUGS("AnimatedObjects") << vobj_name << " calling unlinkControlAvatar()" << LL_ENDL; - vobj->unlinkControlAvatar(); - } - } - + bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); bool any_rigged_face = false; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 7b341ef5e0..1c7f3fd693 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -11683,6 +11683,14 @@ You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user. type="notify"> fail Unable to create requested object. The region is full. + + + + fail +Unable to create requested animated object because it exceeds the size limit.