From aa37a0b539fe61bc7acf9ea48a5c68b65e46a0d1 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 17 Mar 2019 01:08:34 -0500 Subject: [PATCH] Intermediary commit #3 --- indra/newview/app_settings/settings.xml | 21 +++-- indra/newview/llagent.cpp | 5 +- indra/newview/lldrawpoolavatar.cpp | 26 ++++++ indra/newview/lldrawpoolavatar.h | 2 + indra/newview/llfloatermodelpreview.cpp | 89 +++++++++++++------ indra/newview/llfloatermodelpreview.h | 5 +- indra/newview/llfloaterscriptdebug.cpp | 35 ++++++-- indra/newview/llselectmgr.cpp | 101 ++++++++++++++++++---- indra/newview/llselectmgr.h | 5 ++ indra/newview/llviewerjointattachment.cpp | 19 ++++ indra/newview/llviewerjointattachment.h | 1 + indra/newview/llviewerobject.cpp | 92 ++++++++++++++++++++ indra/newview/llviewerobject.h | 6 ++ indra/newview/llvoavatar.cpp | 101 ++++++++++++++++++---- indra/newview/llvoavatar.h | 9 +- indra/newview/llvovolume.cpp | 20 +++-- indra/newview/llvovolume.h | 2 +- indra/newview/pipeline.cpp | 2 + indra/newview/pipeline.h | 2 + 19 files changed, 464 insertions(+), 79 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f7a35ff13..9d6846127 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5347,6 +5347,17 @@ This should be as low as possible, but too low may break functionality Value + AnimatedObjectsIgnoreLimits + + Comment + Ignore server-enforced limits on animated objects. This is only useful for server testing. + Persist + 1 + Type + Boolean + Value + 0 + DebugAvatarAppearanceMessage Comment @@ -12779,7 +12790,7 @@ This should be as low as possible, but too low may break functionality RenderSSAOEffect Comment - Multiplier for (1) value for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.) + Multiplier for (1) value and (2) saturation (HSV definition), for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.) Persist 1 Type @@ -13267,13 +13278,13 @@ This should be as low as possible, but too low may break functionality Type F32 Value - 384 + 368.0 RenderDeferred Comment - Use deferred rendering pipeline. + Use deferred rendering pipeline (Advanced Lighting Model). Persist 1 Type @@ -13411,7 +13422,7 @@ This should be as low as possible, but too low may break functionality Type U32 Value - 4 + 4 RenderShadowBlurDistFactor @@ -14174,7 +14185,7 @@ This should be as low as possible, but too low may break functionality RenderAutoMuteByteLimit Comment - Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit). + If avatar attachment size exceed this value (in bytes) attachment will not be rendered. Excludes attachments worn by own avatar. Persist 1 Type diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 29934eabd..498e3755c 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4018,9 +4018,12 @@ bool LLAgent::teleportCore(bool is_local) /*static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); if(!hide_tp_screen) { + // AscentDisableTeleportScreens TRUE might be broken..*/ + //release geometry from old location gPipeline.resetVertexBuffers(); - }*/ + LLSpatialPartition::sTeleportRequested = TRUE; + /*}*/ if (gSavedSettings.getBOOL("SpeedRez")) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index b81820d62..b82900c58 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() //----------------------------------------------------------------------------- diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index dba3c1633..acc11a95e 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -67,6 +67,8 @@ public: virtual S32 getVertexShaderLevel() const; LLDrawPoolAvatar(); + ~LLDrawPoolAvatar(); + /*virtual*/ BOOL isDead(); static const LLMatrix4a& getModelView(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9f798c68c..e914825df 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -500,7 +500,9 @@ void LLFloaterModelPreview::onClickCalculateBtn() mUploadModelUrl.clear(); gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, - childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false, + childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, + mUploadModelUrl, false, getWholeModelFeeObserverHandle()); toggleCalculateButton(false); @@ -1194,6 +1196,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex() , mLodsQuery() +, mLodsWithParsingError() , mPelvisZOffset( 0.0f ) , mLegacyRigValid( false ) , mRigValidJointUpload( false ) @@ -1258,6 +1261,10 @@ LLModelPreview::~LLModelPreview() // glod.dll!glodShutdown() + 0x77 bytes // //glodShutdown(); + if(mModelLoader) + { + mModelLoader->shutdown(); + } } U32 LLModelPreview::calcResourceCost() @@ -1373,6 +1380,15 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z)); } +void LLFloaterModelPreview::setPreviewLOD(S32 lod) +{ + if (mModelPreview) + { + mModelPreview->setPreviewLOD(lod); + } +} + + void LLModelPreview::rebuildUploadData() { assert_main_thread(); @@ -1749,16 +1765,24 @@ void LLModelPreview::clearModel(S32 lod) void LLModelPreview::getJointAliases( JointMap& joint_map) { - // Get all standard skeleton joints from the preview avatar. - LLVOAvatar *av = getPreviewAvatar(); - - //Joint names and aliases come from avatar_skeleton.xml - - joint_map = av->getJointAliases(); - for (S32 i = 0; i < av->mCollisionVolumes.size(); i++) - { - joint_map[av->mCollisionVolumes[i]->getName()] = av->mCollisionVolumes[i]->getName(); - } + // Get all standard skeleton joints from the preview avatar. + LLVOAvatar *av = getPreviewAvatar(); + + //Joint names and aliases come from avatar_skeleton.xml + + joint_map = av->getJointAliases(); + + std::vector cv_names, attach_names; + av->getSortedJointNames(1, cv_names); + av->getSortedJointNames(2, attach_names); + for (std::vector::iterator it = cv_names.begin(); it != cv_names.end(); ++it) + { + joint_map[*it] = *it; + } + for (std::vector::iterator it = attach_names.begin(); it != attach_names.end(); ++it) + { + joint_map[*it] = *it; + } } void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm) @@ -1785,8 +1809,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable // this is the initial file picking. Close the whole floater // if we don't have a base model to show for high LOD. mFMP->close(); - mLoading = false; + } + mLoading = false; return; } @@ -1937,7 +1962,14 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { mLoading = false; mModelLoader = NULL; - return; + mLodsWithParsingError.push_back(loaded_lod); + return ; + } + + mLodsWithParsingError.erase(std::remove(mLodsWithParsingError.begin(), mLodsWithParsingError.end(), loaded_lod), mLodsWithParsingError.end()); + if(mLodsWithParsingError.empty()) + { + mFMP->childEnable( "calculate_btn" ); } // Copy determinations about rig so UI will reflect them @@ -3517,24 +3549,19 @@ LLVector3 LLModelPreview::getTranslationForJointOffset(std::string joint) //----------------------------------------------------------------------------- // createPreviewAvatar //----------------------------------------------------------------------------- -void LLModelPreview::createPreviewAvatar(void) +void LLModelPreview::createPreviewAvatar( void ) { - mPreviewAvatar = (LLVOAvatar*)gObjectList.createObjectViewer( LL_PCODE_LEGACY_AVATAR, gAgent.getRegion() ); - if (mPreviewAvatar) + mPreviewAvatar = (LLVOAvatar*)gObjectList.createObjectViewer( LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR ); + if ( mPreviewAvatar ) { - mPreviewAvatar->createDrawable(&gPipeline); - mPreviewAvatar->mIsDummy = TRUE; + mPreviewAvatar->createDrawable( &gPipeline ); mPreviewAvatar->mSpecialRenderMode = 1; - mPreviewAvatar->setPositionAgent(LLVector3::zero); - mPreviewAvatar->slamPosition(); - mPreviewAvatar->updateJointLODs(); - mPreviewAvatar->updateGeometry(mPreviewAvatar->mDrawable); - mPreviewAvatar->startMotion(ANIM_AGENT_STAND); + mPreviewAvatar->startMotion( ANIM_AGENT_STAND ); mPreviewAvatar->hideSkirt(); } else { - LL_INFOS() <<"Failed to create preview avatar for upload model window"<mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl, + mp->childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, + mp->mUploadModelUrl, true, LLHandle(), mp->getWholeModelUploadObserverHandle()); } @@ -4614,3 +4643,13 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::stri LLNotificationsUtil::add("MeshUploadPermError"); } + +bool LLFloaterModelPreview::isModelLoading() +{ + if(mModelPreview) + { + return mModelPreview->mLoading; + } + return false; +} + diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 796832a9b..7585dce93 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -91,7 +91,7 @@ public: static void setUploadAmount(S32 amount) { sUploadAmount = amount; } void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); - + void setPreviewLOD(S32 lod); void onBrowseLOD(S32 lod); static void onReset(void* data); @@ -111,6 +111,8 @@ public: void enableViewOption(const std::string& option); void disableViewOption(const std::string& option); + bool isModelLoading(); + // shows warning message if agent has no permissions to upload model /*virtual*/ void onPermissionsReceived(const LLSD& result); @@ -302,6 +304,7 @@ public: static bool sIgnoreLoadedCallback; std::vector mLodsQuery; + std::vector mLodsWithParsingError; protected: diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index 83404d746..ce70602a5 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -39,6 +39,7 @@ #include "llrect.h" #include "llerror.h" #include "llstring.h" +#include "llvoavatarself.h" #include "message.h" // project include @@ -127,10 +128,28 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: LLViewerObject* objectp = gObjectList.findObject(source_id); std::string floater_label; + // Handle /me messages. + std::string prefix = utf8mesg.substr(0, 4); + std::string message = (prefix == "/me " || prefix == "/me'") ? user_name + utf8mesg.substr(3) : utf8mesg; + if (objectp) { - objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); - floater_label = llformat("%s(%.2f, %.2f)", user_name.c_str(), objectp->getPositionRegion().mV[VX], objectp->getPositionRegion().mV[VY]); + if(objectp->isHUDAttachment()) + { + if (isAgentAvatarValid()) + { + ((LLViewerObject*)gAgentAvatarp)->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); + } + } + else + { + objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); + } + floater_label = llformat("%s(%.0f, %.0f, %.0f)", + user_name.c_str(), + objectp->getPositionRegion().mV[VX], + objectp->getPositionRegion().mV[VY], + objectp->getPositionRegion().mV[VZ]); } else { @@ -142,11 +161,17 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: // add to "All" floater LLFloaterScriptDebugOutput* floaterp = LLFloaterScriptDebugOutput::getFloaterByID(LLUUID::null); - floaterp->addLine(utf8mesg, user_name, color); - + if (floaterp) + { + floaterp->addLine(message, user_name, color); + } + // add to specific script instance floater floaterp = LLFloaterScriptDebugOutput::getFloaterByID(source_id); - floaterp->addLine(utf8mesg, floater_label, color); + if (floaterp) + { + floaterp->addLine(message, floater_label, color); + } } // diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7ec273c76..7437af538 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -661,6 +661,10 @@ bool LLSelectMgr::enableLinkObjects() new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); } } + if (!LLSelectMgr::getInstance()->getSelection()->checkAnimatedObjectLinkable()) + { + new_value = false; + } // [RLVa:KB] - Checked: 2011-03-19 (RLVa-1.3.0f) | Modified: RLVa-0.2.0g if ( (new_value) && ((rlv_handler_t::isEnabled()) && (!RlvActions::canStand())) ) { @@ -967,6 +971,10 @@ LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 iter != objects.end(); ++iter) { LLViewerObject* cur_objectp = *iter; + if(!cur_objectp || cur_objectp->isDead()) + { + continue; + } LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); nodep->selectTE(face, TRUE); mHoverObjects->addNodeAtEnd(nodep); @@ -6522,7 +6530,6 @@ void LLSelectMgr::updateSelectionCenter() mSelectionCenterGlobal.clearVec(); mShowSelection = FALSE; mSelectionBBox = LLBBox(); - mPauseRequests.clear(); resetAgentHUDZoom(); } @@ -6530,21 +6537,7 @@ void LLSelectMgr::updateSelectionCenter() { mSelectedObjects->mSelectType = getSelectTypeForObject(object); - if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) - { - // Freeze avatars with a selected attachment, and all avatars with synchronized motions, if any. - LLVOAvatar* avatar = object->getAvatar(); - // It is possible that 'avatar' is NULL despite this being an attachment because of some race condition. - // In that case just don't freeze the avatar. - if (avatar) - { - avatar->pauseAllSyncedCharacters(mPauseRequests); - } - } - else - { - mPauseRequests.clear(); - } + if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) { @@ -6622,6 +6615,53 @@ void LLSelectMgr::updateSelectionCenter() { gEditMenuHandler = NULL; } + + pauseAssociatedAvatars(); +} + +//----------------------------------------------------------------------------- +// pauseAssociatedAvatars +// +// If the selection includes an attachment or an animated object, the +// associated avatars should pause their animations until they are no +// longer selected. +//----------------------------------------------------------------------------- +void LLSelectMgr::pauseAssociatedAvatars() +{ + mPauseRequests.clear(); + + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object) + continue; + + mSelectedObjects->mSelectType = getSelectTypeForObject(object); + + if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && + isAgentAvatarValid() && object->getParent() != NULL) + { + if (object->isAnimatedObject()) + { + LLVOAvatar* avatar = object->getAvatar(); + if (avatar) + { + avatar->pauseAllSyncedCharacters(mPauseRequests); + } + } + else + { + // Is a regular attachment. Pause the avatar it's attached to. + LLVOAvatar* avatar = object->getAvatar(); + if (avatar) + { + avatar->pauseAllSyncedCharacters(mPauseRequests); + } + } + } + } } void LLSelectMgr::updatePointAt() @@ -7154,7 +7194,9 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount(S32* vcount) if (object) { - count += object->getTriangleCount(vcount); + S32 vt = 0; + count += object->getTriangleCount(&vt); + *vcount += vt; } } @@ -7283,6 +7325,31 @@ bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func) return result; } +bool LLObjectSelection::checkAnimatedObjectEstTris() +{ + F32 est_tris = 0; + F32 max_tris = 0; + S32 anim_count = 0; + for (root_iterator iter = root_begin(); iter != root_end(); ++iter) + { + LLViewerObject* object = (*iter)->getObject(); + if (!object) + continue; + if (object->isAnimatedObject()) + { + anim_count++; + } + est_tris += object->recursiveGetEstTrianglesMax(); + max_tris = llmax((F32)max_tris,(F32)object->getAnimatedObjectMaxTris()); + } + return anim_count==0 || est_tris <= max_tris; +} + +bool LLObjectSelection::checkAnimatedObjectLinkable() +{ + return checkAnimatedObjectEstTris(); +} + bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly) { bool result = firstonly ? false : true; diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 416e79425..91e7fcaf3 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -311,6 +311,9 @@ public: // returns TRUE is any node is currenly worn as an attachment BOOL isAttachment(); + bool checkAnimatedObjectEstTris(); + bool checkAnimatedObjectLinkable(); + // Apply functors to various subsets of the selected objects // If firstonly is FALSE, returns the AND of all apply() calls. // Else returns TRUE immediately if any apply() call succeeds (i.e. OR with early exit) @@ -699,6 +702,8 @@ public: LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; } void updateSelectionCenter(); + void pauseAssociatedAvatars(); + void resetAgentHUDZoom(); void setAgentHUDZoom(F32 target_zoom, F32 current_zoom); void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index c80963db3..1b118ec63 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -361,6 +361,25 @@ void LLViewerJointAttachment::setOriginalPosition(LLVector3& position) setPosition(position); } +//----------------------------------------------------------------------------- +// getNumAnimatedObjects() +//----------------------------------------------------------------------------- +S32 LLViewerJointAttachment::getNumAnimatedObjects() const +{ + S32 count = 0; + for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) + { + const LLViewerObject *attached_object = *iter; + if (attached_object->isAnimatedObject()) + { + count++; + } + } + return count; +} + //----------------------------------------------------------------------------- // clampObjectPosition() //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h index bb94c3678..20eb42957 100644 --- a/indra/newview/llviewerjointattachment.h +++ b/indra/newview/llviewerjointattachment.h @@ -87,6 +87,7 @@ public: S32 getGroup() const { return mGroup; } S32 getPieSlice() const { return mPieSlice; } S32 getNumObjects() const { return mAttachedObjects.size(); } + S32 getNumAnimatedObjects() const; void clampObjectPosition(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f4aad9bf0..ab5df4275 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3416,6 +3416,47 @@ F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscal { return 0.f; } +F32 LLViewerObject::recursiveGetEstTrianglesMax() const +{ + F32 est_tris = getEstTrianglesMax(); + for (child_list_t::const_iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + const LLViewerObject* child = *iter; + if (!child->isAvatar()) + { + est_tris += child->recursiveGetEstTrianglesMax(); + } + } + return est_tris; +} + +S32 LLViewerObject::getAnimatedObjectMaxTris() const +{ + S32 max_tris = 0; + if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) + { + max_tris = S32_MAX; + } + else + { + if (gAgent.getRegion()) + { + LLSD features; + gAgent.getRegion()->getSimulatorFeatures(features); + if (features.has("AnimatedObjects")) + { + max_tris = features["AnimatedObjects"]["AnimatedObjectMaxTris"].asInteger(); + } + } + } + return max_tris; +} + +F32 LLViewerObject::getEstTrianglesMax() const +{ + return 0.f; +} U32 LLViewerObject::getTriangleCount(S32* vcount) const { @@ -3427,6 +3468,57 @@ U32 LLViewerObject::getHighLODTriangleCount() return 0; } +U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const +{ + S32 total_tris = getTriangleCount(vcount); + LLViewerObject::const_child_list_t& child_list = getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + if (childp) + { + total_tris += childp->getTriangleCount(vcount); + } + } + return total_tris; +} + +// This is using the stored surface area for each volume (which +// defaults to 1.0 for the case of everything except a sculpt) and +// then scaling it linearly based on the largest dimension in the +// prim's scale. Should revisit at some point. +F32 LLViewerObject::recursiveGetScaledSurfaceArea() const +{ + F32 area = 0.f; + const LLDrawable* drawable = mDrawable; + if (drawable) + { + const LLVOVolume* volume = drawable->getVOVolume(); + if (volume) + { + if (volume->getVolume()) + { + const LLVector3& scale = volume->getScale(); + area += volume->getVolume()->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } + LLViewerObject::const_child_list_t children = volume->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator child_iter = children.begin(); + child_iter != children.end(); + ++child_iter) + { + LLViewerObject* child_obj = *child_iter; + LLVOVolume *child = dynamic_cast( child_obj ); + if (child && child->getVolume()) + { + const LLVector3& scale = child->getScale(); + area += child->getVolume()->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } + } + } + } + return area; +} void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { if(mDrawable.isNull()) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 9f6d0a817..6177cb2dc 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -366,8 +366,14 @@ public: virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const; + S32 getAnimatedObjectMaxTris() const; + F32 recursiveGetEstTrianglesMax() const; + virtual F32 getEstTrianglesMax() const; virtual U32 getTriangleCount(S32* vcount = NULL) const; virtual U32 getHighLODTriangleCount(); + F32 recursiveGetScaledSurfaceArea() const; + + U32 recursiveGetTriangleCount(S32* vcount = NULL) const; void setObjectCost(F32 cost); F32 getObjectCost(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d70df9892..88650eb64 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1669,7 +1669,7 @@ const LLVector3 LLVOAvatar::getRenderPosition() const { return getPositionAgent(); } - else if (isRoot() || !mDrawable->getParent()) + else if (isRoot()/* || !mDrawable->getParent()*/) // Animesh- { F32 fixup; if ( hasPelvisFixup( fixup) ) @@ -2311,7 +2311,6 @@ void LLVOAvatar::buildCharacter() { startDefaultMotions(); } - startDefaultMotions(); //------------------------------------------------------------------------- // restart any currently active motions @@ -4896,6 +4895,7 @@ void LLVOAvatar::updateVisibility() LL_INFOS() << "WPA: " << wrist_right_pos_agent << LL_ENDL;*/ +#if SLOW_ATTACHMENT_LIST for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -4907,6 +4907,13 @@ void LLVOAvatar::updateVisibility() ++attachment_iter) { if (LLViewerObject *attached_object = (*attachment_iter)) +#else + for (auto& iter : mAttachedObjectsVector) + {{ + const LLViewerObject *attached_object = iter.first; + const LLViewerJointAttachment *attachment = iter.second; + if (attachment) +#endif { if (attached_object && attached_object->mDrawable->isVisible()) { @@ -5911,7 +5918,10 @@ void LLVOAvatar::processAnimationStateChanges() else if (mInAir && !isSitting()) { stopMotion(ANIM_AGENT_WALK_ADJUST); - startMotion(ANIM_AGENT_FLY_ADJUST); + if (mEnableDefaultMotions) + { + startMotion(ANIM_AGENT_FLY_ADJUST); + } } else { @@ -5921,13 +5931,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 @@ -7330,14 +7346,6 @@ U32 LLVOAvatar::getNumAttachments() const return num_attachments; } -//----------------------------------------------------------------------------- -// canAttachMoreObjects() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::canAttachMoreObjects() const -{ - return (getNumAttachments() < MAX_AGENT_ATTACHMENTS); -} - //----------------------------------------------------------------------------- // canAttachMoreObjects() // Returns true if we can attach more objects. @@ -7347,6 +7355,57 @@ BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const return (getNumAttachments() + n) <= MAX_AGENT_ATTACHMENTS; } +//----------------------------------------------------------------------------- +// getNumAnimatedObjectAttachments() +//----------------------------------------------------------------------------- +U32 LLVOAvatar::getNumAnimatedObjectAttachments() const +{ + U32 num_attachments = 0; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; + num_attachments += attachment_pt->getNumAnimatedObjects(); + } + return num_attachments; +} + +//----------------------------------------------------------------------------- +// getMaxAnimatedObjectAttachments() +// Gets from simulator feature if available, otherwise 0. +//----------------------------------------------------------------------------- +U32 LLVOAvatar::getMaxAnimatedObjectAttachments() const +{ + U32 max_attach = 0; + if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) + { + max_attach = MAX_AGENT_ATTACHMENTS; + } + else + { + if (gAgent.getRegion()) + { + LLSD features; + gAgent.getRegion()->getSimulatorFeatures(features); + if (features.has("AnimatedObjects")) + { + max_attach = (U32)llmax(0,features["AnimatedObjects"]["MaxAgentAnimatedObjectAttachments"].asInteger()); + } + } + } + return max_attach; +} + +//----------------------------------------------------------------------------- +// canAttachMoreAnimatedObjects() +// Returns true if we can attach more animated objects. +//----------------------------------------------------------------------------- +BOOL LLVOAvatar::canAttachMoreAnimatedObjects(U32 n) const +{ + return (getNumAnimatedObjectAttachments() + n) <= getMaxAnimatedObjectAttachments(); +} + //----------------------------------------------------------------------------- // lazyAttach() //----------------------------------------------------------------------------- @@ -7830,6 +7889,13 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, bool updateMeshTextures(); } + +// FIXME: We have an mVisible member, set in updateVisibility(), but this +// function doesn't return it! isVisible() and mVisible are used +// different places for different purposes. mVisible seems to be more +// related to whether the actual avatar mesh is shown, and isVisible() +// to whether anything about the avatar is displayed in the scene. +// Maybe better naming could make this clearer? BOOL LLVOAvatar::isVisible() const { return mDrawable.notNull() @@ -9784,7 +9850,12 @@ void LLVOAvatar::updateFreezeCounter(S32 counter) BOOL LLVOAvatar::updateLOD() { - if (isImpostor()) + if (mDrawable.isNull()) + { + return FALSE; + } + + if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry()) { return TRUE; } @@ -9809,7 +9880,7 @@ BOOL LLVOAvatar::updateLOD() return res; } -void LLVOAvatar::updateLODRiggedAttachments( void ) +void LLVOAvatar::updateLODRiggedAttachments() { updateLOD(); rebuildRiggedAttachments(); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 0593f0fc2..de26b616a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -783,9 +783,9 @@ public: static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; + LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); protected: - LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); void lazyAttach(); void rebuildRiggedAttachments( void ); @@ -807,11 +807,12 @@ public: BOOL hasHUDAttachment() const; LLBBox getHUDBBox() const; void resetHUDAttachments(); - BOOL canAttachMoreObjects() const; - BOOL canAttachMoreObjects(U32 n) const; + BOOL canAttachMoreObjects(U32 n=1) const; + U32 getMaxAnimatedObjectAttachments() const; + BOOL canAttachMoreAnimatedObjects(U32 n=1) const; protected: U32 getNumAttachments() const; // O(N), not O(1) - + U32 getNumAnimatedObjectAttachments() const; // O(N), not O(1) //-------------------------------------------------------------------- // Old/nonstandard/Agent-only functions //-------------------------------------------------------------------- diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 54705270d..6447e03ff 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1595,7 +1595,7 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_FLEX("Generate Flexies"); static LLTrace::BlockTimerStatHandle FTM_UPDATE_PRIMITIVES("Update Primitives"); static LLTrace::BlockTimerStatHandle FTM_UPDATE_RIGGED_VOLUME("Update Rigged"); -bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable) +bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) { bool regen_faces = false; @@ -1621,6 +1621,7 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable) if ((new_lod != old_lod) || mSculptChanged) { + compiled = TRUE; sNumLODChanges += new_num_faces ; if((S32)getNumTEs() != getVolume()->getNumFaces()) @@ -1685,6 +1686,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) group->dirtyMesh(); } + BOOL compiled = FALSE; + updateRelativeXform(); if (mDrawable.isNull()) // Not sure why this is happening, but it is... @@ -1700,12 +1703,13 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mVolumeChanged) { - was_regen_faces = lodOrSculptChanged(drawable); + was_regen_faces = lodOrSculptChanged(drawable, compiled); drawable->setState(LLDrawable::REBUILD_VOLUME); } else if (mSculptChanged || mLODChanged) { - was_regen_faces = lodOrSculptChanged(drawable); + compiled = TRUE; + was_regen_faces = lodOrSculptChanged(drawable, compiled); } if (!was_regen_faces) { @@ -1718,13 +1722,15 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) else if (mLODChanged || mSculptChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); - lodOrSculptChanged(drawable); + compiled = TRUE; + lodOrSculptChanged(drawable, compiled); genBBoxes(FALSE); } // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local else { + compiled = TRUE; // All it did was move or we changed the texture coordinate offset LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); genBBoxes(FALSE); @@ -1732,6 +1738,10 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) // Update face flags updateFaceFlags(); + if(compiled) + { + LLPipeline::sCompiles++; + } mVolumeChanged = FALSE; mLODChanged = FALSE; @@ -4789,7 +4799,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) { continue; } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 9bf1052ef..156669aec 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -363,7 +363,7 @@ protected: void removeMediaImpl(S32 texture_index) ; private: - bool lodOrSculptChanged(LLDrawable *drawable); + bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled); public: diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 608c4c872..81b7480c1 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -290,6 +290,8 @@ void glh_set_last_projection(const LLMatrix4a& mat) void display_update_camera(bool tiling=false); //---------------------------------------- +S32 LLPipeline::sCompiles = 0; + BOOL LLPipeline::sPickAvatar = TRUE; BOOL LLPipeline::sDynamicLOD = TRUE; BOOL LLPipeline::sShowHUDAttachments = TRUE; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 4094fbc8b..ef399c1f8 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -570,6 +570,8 @@ public: S32 mTrianglesDrawn; S32 mNumVisibleNodes; + static S32 sCompiles; + static BOOL sShowHUDAttachments; static BOOL sForceOldBakedUpload; // If true will not use capabilities to upload baked textures. static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write