Merge axon
commit
08dbe24cde
|
|
@ -78,3 +78,10 @@ struct LLContextStatus
|
|||
};
|
||||
|
||||
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status);
|
||||
|
||||
#define dumpStack(tag) \
|
||||
if (debugLoggingEnabled(tag)) \
|
||||
{ \
|
||||
LLCallStack cs; \
|
||||
LL_DEBUGS(tag) << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1297,7 +1297,10 @@ bool LLAppViewer::init()
|
|||
// // situation to do things the Right Way. Anyone who intentionally
|
||||
// // bypasses this mechanism needs no reminder that s/he's shooting
|
||||
// // him/herself in the foot.
|
||||
// LLNotificationsUtil::add("RunLauncher");
|
||||
// if (!beingDebugged())
|
||||
// {
|
||||
// LLNotificationsUtil::add("RunLauncher");
|
||||
// }
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
|
|
|||
|
|
@ -733,6 +733,11 @@ bool LLAppViewerWin32::initParseCommandLine(LLCommandLineParser& clp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLAppViewerWin32::beingDebugged()
|
||||
{
|
||||
return IsDebuggerPresent();
|
||||
}
|
||||
|
||||
bool LLAppViewerWin32::restoreErrorTrap()
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ protected:
|
|||
virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
|
||||
virtual bool initParseCommandLine(LLCommandLineParser& clp);
|
||||
|
||||
virtual bool beingDebugged();
|
||||
virtual bool restoreErrorTrap();
|
||||
virtual void initCrashReporting(bool reportFreeze);
|
||||
|
||||
|
|
|
|||
|
|
@ -367,8 +367,17 @@ void LLControlAvatar::updateAnimations()
|
|||
}
|
||||
}
|
||||
}
|
||||
mSignaledAnimations = anims;
|
||||
if (!mPlaying && anims.size()>0)
|
||||
{
|
||||
mPlaying = true;
|
||||
if (!mRootVolp->isAnySelected())
|
||||
{
|
||||
updateVolumeGeom();
|
||||
mRootVolp->recursiveMarkForUpdate(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
mSignaledAnimations = anims;
|
||||
processAnimationStateChanges();
|
||||
}
|
||||
|
||||
|
|
@ -405,3 +414,16 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
|
|||
|
||||
return hit;
|
||||
}
|
||||
|
||||
// virtual
|
||||
std::string LLControlAvatar::getFullname() const
|
||||
{
|
||||
if (mRootVolp)
|
||||
{
|
||||
return "AO_" + mRootVolp->getID().getString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "AO_no_root_vol";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ public:
|
|||
|
||||
virtual void updateDebugText();
|
||||
|
||||
virtual std::string getFullname() const;
|
||||
|
||||
bool mPlaying;
|
||||
|
||||
F32 mGlobalScale;
|
||||
|
|
|
|||
|
|
@ -1832,7 +1832,19 @@ class LLAdvancedEnableAppearanceToXML : public view_listener_t
|
|||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
|
||||
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (obj && obj->isAnimatedObject() && obj->getControlAvatar())
|
||||
{
|
||||
return gSavedSettings.getBOOL("DebugAnimatedObjects");
|
||||
}
|
||||
else if (obj && obj->isAttachment() && obj->getAvatar())
|
||||
{
|
||||
return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1841,8 +1853,8 @@ class LLAdvancedAppearanceToXML : public view_listener_t
|
|||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
std::string emptyname;
|
||||
LLVOAvatar* avatar =
|
||||
find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
||||
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
LLVOAvatar* avatar = obj->getAvatar();
|
||||
if (!avatar)
|
||||
{
|
||||
avatar = gAgentAvatarp;
|
||||
|
|
@ -7516,7 +7528,12 @@ class LLAvatarResetSkeleton: public view_listener_t
|
|||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
||||
LLVOAvatar* avatar = NULL;
|
||||
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (obj)
|
||||
{
|
||||
avatar = obj->getAvatar();
|
||||
}
|
||||
if(avatar)
|
||||
{
|
||||
avatar->resetSkeleton(false);
|
||||
|
|
@ -7525,6 +7542,20 @@ class LLAvatarResetSkeleton: public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAvatarEnableResetSkeleton: public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (obj && obj->getAvatar())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class LLAvatarResetSkeletonAndAnimations : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -11550,6 +11581,7 @@ void initialize_menus()
|
|||
|
||||
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
|
||||
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
|
||||
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
|
||||
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
|
||||
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
|
||||
|
||||
|
|
|
|||
|
|
@ -6698,42 +6698,6 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
|
|||
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
|
||||
LL_DEBUGS("AnimatedObjects") << "processing object animation requests, num_blocks " << num_blocks << LL_ENDL;
|
||||
|
||||
#if 1
|
||||
// Here we go into skinned mode once, the first time we get an
|
||||
// animation request, and then stay there. This is probably the
|
||||
// normally desired behavior.
|
||||
if (!avatarp->mPlaying)
|
||||
{
|
||||
avatarp->mPlaying = true;
|
||||
if (!avatarp->mRootVolp->isAnySelected())
|
||||
{
|
||||
avatarp->updateVolumeGeom();
|
||||
avatarp->mRootVolp->recursiveMarkForUpdate(TRUE);
|
||||
}
|
||||
}
|
||||
#else// AXON REMOVE BEFORE RELEASE?
|
||||
// In this block we switch back into static mode when no animations are
|
||||
// playing. This is mostly useful for debugging.
|
||||
if (num_blocks > 0 && !avatarp->mPlaying)
|
||||
{
|
||||
avatarp->mPlaying = true;
|
||||
if (!avatarp->mRootVolp->isAnySelected())
|
||||
{
|
||||
avatarp->updateVolumeGeom();
|
||||
avatarp->mRootVolp->recursiveMarkForUpdate(TRUE);
|
||||
}
|
||||
}
|
||||
else if (num_blocks == 0 && avatarp->mPlaying)
|
||||
{
|
||||
avatarp->mPlaying = false;
|
||||
if (!avatarp->mRootVolp->isAnySelected())
|
||||
{
|
||||
avatarp->updateVolumeGeom();
|
||||
avatarp->mRootVolp->recursiveMarkForUpdate(TRUE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
volp->mObjectSignaledAnimations.clear();
|
||||
|
||||
for( S32 i = 0; i < num_blocks; i++ )
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@
|
|||
#include "llfloaterperms.h"
|
||||
#include "llvocache.h"
|
||||
#include "llcleanup.h"
|
||||
#include "llcallstack.h"
|
||||
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
|
||||
#include "rlvactions.h"
|
||||
#include "rlvcommon.h"
|
||||
|
|
@ -154,6 +155,9 @@ static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
|
|||
// static
|
||||
LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, S32 flags)
|
||||
{
|
||||
LL_DEBUGS("ObjectUpdate") << "creating " << id << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
LLViewerObject *res = NULL;
|
||||
LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT);
|
||||
|
||||
|
|
@ -906,9 +910,18 @@ void LLViewerObject::addChild(LLViewerObject *childp)
|
|||
if(childp->setParent(this))
|
||||
{
|
||||
mChildList.push_back(childp);
|
||||
childp->afterReparent();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent)
|
||||
{
|
||||
}
|
||||
|
||||
void LLViewerObject::afterReparent()
|
||||
{
|
||||
}
|
||||
|
||||
void LLViewerObject::removeChild(LLViewerObject *childp)
|
||||
{
|
||||
for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
|
||||
|
|
@ -1128,6 +1141,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
{
|
||||
LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
U32 retval = 0x0;
|
||||
|
||||
// If region is removed from the list it is also deleted.
|
||||
|
|
@ -1182,10 +1198,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
F32 time_dilation = 1.f;
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
U16 time_dilation16;
|
||||
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
|
||||
time_dilation = ((F32) time_dilation16) / 65535.f;
|
||||
mRegionp->setTimeDilation(time_dilation);
|
||||
U16 time_dilation16;
|
||||
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
|
||||
time_dilation = ((F32) time_dilation16) / 65535.f;
|
||||
mRegionp->setTimeDilation(time_dilation);
|
||||
}
|
||||
|
||||
// this will be used to determine if we've really changed position
|
||||
|
|
@ -3055,14 +3071,14 @@ void LLViewerObject::updateControlAvatar()
|
|||
}
|
||||
if (any_mesh)
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%u", (U32) root);
|
||||
std::string vobj_name = llformat("Vol%p", 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);
|
||||
std::string vobj_name = llformat("Vol%p", root);
|
||||
LL_DEBUGS("AnimatedObjects") << vobj_name << " calling unlinkControlAvatar()" << LL_ENDL;
|
||||
root->unlinkControlAvatar();
|
||||
}
|
||||
|
|
@ -3079,10 +3095,14 @@ void LLViewerObject::linkControlAvatar()
|
|||
return;
|
||||
}
|
||||
mControlAvatar = LLControlAvatar::createControlAvatar(volp);
|
||||
LL_DEBUGS("AnimatedObjects") << volp->getID()
|
||||
<< " created control av for "
|
||||
<< (S32) (1+volp->numChildren()) << " prims" << LL_ENDL;
|
||||
}
|
||||
if (getControlAvatar())
|
||||
{
|
||||
getControlAvatar()->rebuildAttachmentOverrides();
|
||||
getControlAvatar()->updateAnimations();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -259,6 +259,8 @@ public:
|
|||
*/
|
||||
|
||||
virtual BOOL setParent(LLViewerObject* parent);
|
||||
virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
|
||||
virtual void afterReparent();
|
||||
virtual void addChild(LLViewerObject *childp);
|
||||
virtual void removeChild(LLViewerObject *childp);
|
||||
const_child_list_t& getChildren() const { return mChildList; }
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
#include "u64.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "lldatapacker.h"
|
||||
#include "llcallstack.h"
|
||||
#ifdef LL_USESYSTEMLIBS
|
||||
#include <zlib.h>
|
||||
#else
|
||||
|
|
@ -256,6 +257,10 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
|
|||
}
|
||||
|
||||
// ignore returned flags
|
||||
LL_DEBUGS("ObjectUpdate") << "uuid " << objectp->mID << " calling processUpdateMessage "
|
||||
<< objectp << " just_created " << just_created << " from_cache " << from_cache << " msg " << msg << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
objectp->processUpdateMessage(msg, user_data, i, update_type, dpp);
|
||||
|
||||
if (objectp->isDead())
|
||||
|
|
@ -398,7 +403,10 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*
|
|||
if (!objectp)
|
||||
{
|
||||
objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID());
|
||||
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << "uuid " << fullid << " created objectp " << objectp << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
if (!objectp)
|
||||
{
|
||||
LL_INFOS() << "createObject failure for object: " << fullid << LL_ENDL;
|
||||
|
|
@ -517,6 +525,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
compressed_dp.reset();
|
||||
|
||||
uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
|
||||
LL_DEBUGS("ObjectUpdate") << "got binary data from message to compressed_dpbuffer" << LL_ENDL;
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
|
||||
compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
|
||||
|
||||
|
|
@ -576,6 +585,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
// LL_WARNS() << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << LL_ENDL;
|
||||
mNumUnknownUpdates++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ObjectUpdate") << "Non-full, non-compressed update, obj " << local_id << ", global ID " << fullid << " from " << mesgsys->getSender() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else // OUT_FULL only?
|
||||
{
|
||||
|
|
@ -584,11 +597,19 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
||||
msg_size += sizeof(LLUUID);
|
||||
msg_size += sizeof(U32);
|
||||
// LL_INFOS() << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << LL_ENDL;
|
||||
LL_DEBUGS("ObjectUpdate") << "Full Update, obj " << local_id << ", global ID " << fullid << " from " << mesgsys->getSender() << LL_ENDL;
|
||||
}
|
||||
objectp = findObject(fullid);
|
||||
LL_DEBUGS("AnimatedObjects") << "processObjectUpdate for uuid " << fullid << " objectp " << objectp << LL_ENDL;
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
LL_DEBUGS("ObjectUpdate") << "uuid " << fullid << " received compressed data from message (earlier in function)" << LL_ENDL;
|
||||
}
|
||||
LL_DEBUGS("ObjectUpdate") << "uuid " << fullid << " objectp " << objectp
|
||||
<< " update_cache " << (S32) update_cache << " compressed " << compressed
|
||||
<< " update_type " << update_type << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
if(update_cache)
|
||||
{
|
||||
objectp = regionp->updateCacheEntry(local_id, objectp, update_type);
|
||||
|
|
@ -677,7 +698,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
// </FS:Ansariel>
|
||||
|
||||
objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());
|
||||
LL_DEBUGS("AnimatedObjects") << "creating object " << fullid << " result " << objectp << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << "creating object " << fullid << " result " << objectp << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
if (!objectp)
|
||||
{
|
||||
LL_INFOS() << "createObject failure for object: " << fullid << LL_ENDL;
|
||||
|
|
@ -776,12 +800,17 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
|
|||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
|
||||
msg_size += sizeof(U32) * 2;
|
||||
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << "got probe for id " << id << " crc " << crc << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
// Lookup data packer and add this id to cache miss lists if necessary.
|
||||
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
|
||||
if(!regionp->probeCache(id, crc, flags, cache_miss_type))
|
||||
{
|
||||
// Cache Miss.
|
||||
LL_DEBUGS("ObjectUpdate") << "cache miss for id " << id << " crc " << crc << " miss type " << (S32) cache_miss_type << LL_ENDL;
|
||||
|
||||
recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
|
||||
|
||||
continue; // no data packer, skip this object
|
||||
|
|
@ -1386,6 +1415,9 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
|
|||
// Cleanup any references we have to this object
|
||||
// Remove from object map so noone can look it up.
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << " dereferencing id " << objectp->mID << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
mUUIDObjectMap.erase(objectp->mID);
|
||||
|
||||
//if (objectp->getRegion())
|
||||
|
|
@ -2186,8 +2218,9 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L
|
|||
{
|
||||
llassert_always(uuid.notNull());
|
||||
|
||||
LL_DEBUGS("AnimatedObjects") << "createObjectFromCache creating " << uuid << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << "creating " << uuid << " local_id " << local_id << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp);
|
||||
if (!objectp)
|
||||
{
|
||||
|
|
@ -2234,7 +2267,9 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe
|
|||
{
|
||||
fullid = uuid;
|
||||
}
|
||||
LL_DEBUGS("AnimatedObjects") << "createObject creating " << fullid << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << "createObject creating " << fullid << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
|
||||
if (!objectp)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
#include "llcoros.h"
|
||||
#include "lleventcoro.h"
|
||||
#include "llcorehttputil.h"
|
||||
#include "llcallstack.h"
|
||||
|
||||
// <FS:CR> Opensim
|
||||
#include "llviewerparcelmgr.h" //Aurora Sim
|
||||
|
|
@ -1329,7 +1330,7 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time)
|
|||
LLPointer<LLViewerOctreeGroup> group = *group_iter;
|
||||
if(group->getNumRefs() < 3 || //group to be deleted
|
||||
!group->getOctreeNode() || group->isEmpty()) //group empty
|
||||
{
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2292,6 +2293,24 @@ void LLViewerRegion::getInfo(LLSD& info)
|
|||
info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
|
||||
}
|
||||
|
||||
void LLViewerRegion::requestSimulatorFeatures()
|
||||
{
|
||||
// kick off a request for simulator features
|
||||
std::string url = getCapability("SimulatorFeatures");
|
||||
if (!url.empty())
|
||||
{
|
||||
std::string coroname =
|
||||
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
|
||||
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, url, getHandle()));
|
||||
|
||||
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("AppInit", "SimulatorFeatures") << "SimulatorFeatures cap not set" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
boost::signals2::connection LLViewerRegion::setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb)
|
||||
{
|
||||
return mSimulatorFeaturesReceivedSignal.connect(cb);
|
||||
|
|
@ -2400,7 +2419,7 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
|
|||
{
|
||||
LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
|
||||
if(old_regionp != this && old_regionp)
|
||||
{
|
||||
{
|
||||
LLViewerObject* obj = ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj();
|
||||
if(obj)
|
||||
{
|
||||
|
|
@ -2563,12 +2582,18 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
|
|||
// we've seen this object before
|
||||
if (entry->getCRC() == crc)
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << " got dupe for local_id " << local_id << LL_ENDL;
|
||||
dumpStack("AnimatedObjectsStack");
|
||||
|
||||
// Record a hit
|
||||
entry->recordDupe();
|
||||
result = CACHE_UPDATE_DUPE;
|
||||
}
|
||||
else //CRC changed
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << " got update for local_id " << local_id << LL_ENDL;
|
||||
dumpStack("AnimatedObjectsStack");
|
||||
|
||||
// Update the cache entry
|
||||
entry->updateEntry(crc, dp);
|
||||
|
||||
|
|
@ -2579,6 +2604,9 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << " got first notification for local_id " << local_id << LL_ENDL;
|
||||
dumpStack("AnimatedObjectsStack");
|
||||
|
||||
// we haven't seen this object before
|
||||
// Create new entry and add to map
|
||||
result = CACHE_UPDATE_ADDED;
|
||||
|
|
@ -2683,7 +2711,7 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
|
|||
// Record a hit
|
||||
mRegionCacheHitCount++;
|
||||
entry->recordHit();
|
||||
cache_miss_type = CACHE_MISS_TYPE_NONE;
|
||||
cache_miss_type = CACHE_MISS_TYPE_NONE;
|
||||
entry->setUpdateFlags(flags);
|
||||
|
||||
if(entry->isState(LLVOCacheEntry::ACTIVE))
|
||||
|
|
@ -2706,12 +2734,14 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
|
|||
// LL_INFOS() << "CRC miss for " << local_id << LL_ENDL;
|
||||
|
||||
addCacheMiss(local_id, CACHE_MISS_TYPE_CRC);
|
||||
cache_miss_type = CACHE_MISS_TYPE_CRC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// LL_INFOS() << "Cache miss for " << local_id << LL_ENDL;
|
||||
addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
|
||||
cache_miss_type = CACHE_MISS_TYPE_FULL;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -2748,6 +2778,9 @@ void LLViewerRegion::requestCacheMisses()
|
|||
msg->nextBlockFast(_PREHASH_ObjectData);
|
||||
msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType);
|
||||
msg->addU32Fast(_PREHASH_ID, (*iter).mID);
|
||||
|
||||
LL_DEBUGS("AnimatedObjects") << "Requesting cache missed object " << (*iter).mID << LL_ENDL;
|
||||
|
||||
blocks++;
|
||||
|
||||
if (blocks >= 255)
|
||||
|
|
@ -3154,12 +3187,8 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
|
|||
}
|
||||
else if (name == "SimulatorFeatures")
|
||||
{
|
||||
// kick off a request for simulator features
|
||||
std::string coroname =
|
||||
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
|
||||
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, url, getHandle()));
|
||||
|
||||
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
|
||||
mImpl->mCapabilities["SimulatorFeatures"] = url;
|
||||
requestSimulatorFeatures();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ public:
|
|||
bool meshUploadEnabled() const;
|
||||
|
||||
// has region received its simulator features list? Requires an additional query after caps received.
|
||||
void requestSimulatorFeatures();
|
||||
void setSimulatorFeaturesReceived(bool);
|
||||
bool simulatorFeaturesReceived() const;
|
||||
boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb);
|
||||
|
|
|
|||
|
|
@ -1985,7 +1985,7 @@ void LLVOAvatar::resetVisualParams()
|
|||
void LLVOAvatar::resetSkeleton(bool reset_animations)
|
||||
{
|
||||
LL_DEBUGS("Avatar") << avString() << " reset starts" << LL_ENDL;
|
||||
if (!mLastProcessedAppearance)
|
||||
if (!isControlAvatar() && !mLastProcessedAppearance)
|
||||
{
|
||||
LL_WARNS() << "Can't reset avatar; no appearance message has been received yet." << LL_ENDL;
|
||||
return;
|
||||
|
|
@ -2039,8 +2039,11 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
|
|||
}
|
||||
|
||||
// Reset tweakable params to preserved state
|
||||
bool slam_params = true;
|
||||
applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
|
||||
if (mLastProcessedAppearance)
|
||||
{
|
||||
bool slam_params = true;
|
||||
applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
|
||||
}
|
||||
updateVisualParams();
|
||||
|
||||
// Restore attachment pos overrides
|
||||
|
|
@ -3917,90 +3920,225 @@ bool LLVOAvatar::isInMuteList()
|
|||
return muted;
|
||||
}
|
||||
|
||||
void LLVOAvatar::updateAppearanceMessageDebugText()
|
||||
{
|
||||
S32 central_bake_version = -1;
|
||||
if (getRegion())
|
||||
{
|
||||
central_bake_version = getRegion()->getCentralBakeVersion();
|
||||
}
|
||||
bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
|
||||
bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
|
||||
std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
|
||||
isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
|
||||
all_baked_downloaded ? "B" : "b",
|
||||
mUseLocalAppearance, mIsEditingAppearance,
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
//1, central_bake_version);
|
||||
mUseServerBakes, central_bake_version);
|
||||
// </FS:Ansariel> [Legacy Bake]
|
||||
std::string origin_string = bakedTextureOriginInfo();
|
||||
debug_line += " [" + origin_string + "]";
|
||||
S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
|
||||
S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
|
||||
S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
|
||||
if (isSelf())
|
||||
{
|
||||
debug_line += llformat(" - cof: %d req: %d rcv:%d",
|
||||
curr_cof_version, last_request_cof_version, last_received_cof_version);
|
||||
// <FS:CR> Use LLCachedControl
|
||||
//if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
|
||||
static LLCachedControl<bool> debug_force_appearance_request_failure(gSavedSettings, "DebugForceAppearanceRequestFailure");
|
||||
if (debug_force_appearance_request_failure)
|
||||
// </FS:CR>
|
||||
{
|
||||
debug_line += " FORCING ERRS";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
|
||||
}
|
||||
debug_line += llformat(" bsz-z: %.3f", mBodySize[2]);
|
||||
if (mAvatarOffset[2] != 0.0f)
|
||||
{
|
||||
debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]);
|
||||
}
|
||||
bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled();
|
||||
debug_line += hover_enabled ? " H" : " h";
|
||||
const LLVector3& hover_offset = getHoverOffset();
|
||||
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", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
|
||||
}
|
||||
LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
|
||||
LLVector3 normal;
|
||||
LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
|
||||
resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
|
||||
F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
|
||||
debug_line += llformat(" relev %.3f", rightElev);
|
||||
|
||||
LLVector3 root_pos = mRoot->getPosition();
|
||||
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);
|
||||
|
||||
addDebugText(debug_line);
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset_id)
|
||||
{
|
||||
LLViewerInventoryItem *item = NULL;
|
||||
|
||||
if (vobj)
|
||||
{
|
||||
if (vobj->getInventorySerial()<=0)
|
||||
{
|
||||
vobj->requestInventory();
|
||||
}
|
||||
item = vobj->getInventoryItemByAsset(asset_id);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLUUID asset_id)
|
||||
{
|
||||
LLViewerInventoryItem *item = getObjectInventoryItem(vobj, asset_id);
|
||||
if (!item)
|
||||
{
|
||||
LLViewerObject::const_child_list_t& children = vobj->getChildren();
|
||||
for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
|
||||
it != children.end(); ++it)
|
||||
{
|
||||
LLViewerObject *childp = *it;
|
||||
item = getObjectInventoryItem(childp, asset_id);
|
||||
if (item)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
void LLVOAvatar::updateAnimationDebugText()
|
||||
{
|
||||
for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
|
||||
iter != mMotionController.getActiveMotions().end(); ++iter)
|
||||
{
|
||||
LLMotion* motionp = *iter;
|
||||
if (motionp->getMinPixelArea() < getPixelArea())
|
||||
{
|
||||
std::string output;
|
||||
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;
|
||||
LLViewerInventoryItem *item = recursiveGetObjectInventoryItem(volp,motionp->getID());
|
||||
if (item)
|
||||
{
|
||||
motion_name = item->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (motion_name.empty())
|
||||
{
|
||||
std::string name;
|
||||
if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
|
||||
{
|
||||
name = motionp->getID().asString();
|
||||
LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
|
||||
for (; anim_it != mAnimationSources.end(); ++anim_it)
|
||||
{
|
||||
if (anim_it->second == motionp->getID())
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(anim_it->first);
|
||||
if (!object)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (object->isAvatar())
|
||||
{
|
||||
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)";
|
||||
}
|
||||
}
|
||||
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)";
|
||||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
addDebugText(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOAvatar::updateDebugText()
|
||||
{
|
||||
// Leave mDebugText uncleared here, in case a derived class has added some state first
|
||||
|
||||
// <FS:CR> Use LLCachedControl
|
||||
// <FS:Ansariel> Use cached controls
|
||||
//if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
|
||||
static LLCachedControl<bool> debug_avatar_appearance_message(gSavedSettings, "DebugAvatarAppearanceMessage");
|
||||
if (debug_avatar_appearance_message)
|
||||
// </FS:CR>
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
S32 central_bake_version = -1;
|
||||
if (getRegion())
|
||||
{
|
||||
central_bake_version = getRegion()->getCentralBakeVersion();
|
||||
}
|
||||
bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
|
||||
bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
|
||||
std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
|
||||
isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
|
||||
all_baked_downloaded ? "B" : "b",
|
||||
mUseLocalAppearance, mIsEditingAppearance,
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
//1, central_bake_version);
|
||||
mUseServerBakes, central_bake_version);
|
||||
// </FS:Ansariel> [Legacy Bake]
|
||||
std::string origin_string = bakedTextureOriginInfo();
|
||||
debug_line += " [" + origin_string + "]";
|
||||
S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
|
||||
S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
|
||||
S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
|
||||
if (isSelf())
|
||||
{
|
||||
debug_line += llformat(" - cof: %d req: %d rcv:%d",
|
||||
curr_cof_version, last_request_cof_version, last_received_cof_version);
|
||||
// <FS:CR> Use LLCachedControl
|
||||
//if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
|
||||
static LLCachedControl<bool> debug_force_appearance_request_failure(gSavedSettings, "DebugForceAppearanceRequestFailure");
|
||||
if (debug_force_appearance_request_failure)
|
||||
// </FS:CR>
|
||||
{
|
||||
debug_line += " FORCING ERRS";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
|
||||
}
|
||||
debug_line += llformat(" bsz-z: %.3f", mBodySize[2]);
|
||||
if (mAvatarOffset[2] != 0.0f)
|
||||
{
|
||||
debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]);
|
||||
}
|
||||
bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled();
|
||||
debug_line += hover_enabled ? " H" : " h";
|
||||
const LLVector3& hover_offset = getHoverOffset();
|
||||
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", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
|
||||
}
|
||||
LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
|
||||
LLVector3 normal;
|
||||
LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
|
||||
resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
|
||||
F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
|
||||
debug_line += llformat(" relev %.3f", rightElev);
|
||||
|
||||
LLVector3 root_pos = mRoot->getPosition();
|
||||
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);
|
||||
|
||||
addDebugText(debug_line);
|
||||
updateAppearanceMessageDebugText();
|
||||
}
|
||||
|
||||
// <FS:CR> Use LLCachedControl
|
||||
// <FS:Ansariel> Use cached controls
|
||||
//if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
|
||||
static LLCachedControl<bool> debug_avatar_composite_baked(gSavedSettings, "DebugAvatarCompositeBaked");
|
||||
if (debug_avatar_composite_baked)
|
||||
//if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
|
||||
// </FS:CR>
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
if (!mBakedTextureDebugText.empty())
|
||||
addDebugText(mBakedTextureDebugText);
|
||||
|
|
@ -4009,104 +4147,7 @@ void LLVOAvatar::updateDebugText()
|
|||
// Develop -> Avatar -> Animation Info
|
||||
if (LLVOAvatar::sShowAnimationDebug)
|
||||
{
|
||||
for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
|
||||
iter != mMotionController.getActiveMotions().end(); ++iter)
|
||||
{
|
||||
LLMotion* motionp = *iter;
|
||||
if (motionp->getMinPixelArea() < getPixelArea())
|
||||
{
|
||||
std::string output;
|
||||
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)
|
||||
{
|
||||
if (volp->getInventorySerial()<=0)
|
||||
{
|
||||
volp->requestInventory();
|
||||
}
|
||||
LLViewerInventoryItem* item = volp->getInventoryItemByAsset(motionp->getID());
|
||||
if (item)
|
||||
{
|
||||
motion_name = item->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (motion_name.empty())
|
||||
{
|
||||
std::string name;
|
||||
if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
|
||||
{
|
||||
name = motionp->getID().asString();
|
||||
LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
|
||||
for (; anim_it != mAnimationSources.end(); ++anim_it)
|
||||
{
|
||||
if (anim_it->second == motionp->getID())
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(anim_it->first);
|
||||
if (!object)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (object->isAvatar())
|
||||
{
|
||||
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)";
|
||||
}
|
||||
}
|
||||
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)";
|
||||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
addDebugText(output);
|
||||
}
|
||||
}
|
||||
updateAnimationDebugText();
|
||||
}
|
||||
|
||||
if (!mDebugText.size() && mText.notNull())
|
||||
|
|
@ -6471,6 +6512,9 @@ void LLVOAvatar::rebuildAttachmentOverrides()
|
|||
{
|
||||
LLScopedContextString str("rebuildAttachmentOverrides " + getFullname());
|
||||
|
||||
LL_DEBUGS("AnimatedObjects") << "rebuilding" << LL_ENDL;
|
||||
dumpStack("AnimatedObjectsStack");
|
||||
|
||||
clearAttachmentOverrides();
|
||||
|
||||
// Handle the case that we're resetting the skeleton of an animated object.
|
||||
|
|
@ -6480,6 +6524,8 @@ void LLVOAvatar::rebuildAttachmentOverrides()
|
|||
LLVOVolume *volp = control_av->mRootVolp;
|
||||
if (volp)
|
||||
{
|
||||
LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count "
|
||||
<< (S32) (1+volp->numChildren()) << LL_ENDL;
|
||||
addAttachmentOverridesForObject(volp);
|
||||
}
|
||||
}
|
||||
|
|
@ -6520,6 +6566,9 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
|
|||
|
||||
LLScopedContextString str("addAttachmentOverridesForObject " + vo->getAvatar()->getFullname());
|
||||
|
||||
LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL;
|
||||
dumpStack("AnimatedObjectsStack");
|
||||
|
||||
// Process all children
|
||||
LLViewerObject::const_child_list_t& children = vo->getChildren();
|
||||
for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
|
||||
|
|
@ -6536,9 +6585,13 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerObject *root_object = (LLViewerObject*)vobj->getRoot();
|
||||
LL_DEBUGS("AnimatedObjects") << "trying to add attachment overrides for root object " << root_object->getID() << " prim is " << vobj << LL_ENDL;
|
||||
if (vobj->isMesh() &&
|
||||
((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << "failed to add attachment overrides for root object " << root_object->getID() << " mesh asset not loaded" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
const LLMeshSkinInfo* pSkinData = vobj->getSkinInfo();
|
||||
|
|
@ -6555,6 +6608,8 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
|
|||
{
|
||||
const F32 pelvisZOffset = pSkinData->mPelvisOffset;
|
||||
const LLUUID& mesh_id = pSkinData->mMeshID;
|
||||
|
||||
LL_DEBUGS("AnimatedObjects") << "adding attachment overrides for " << mesh_id << " to root object " << root_object->getID() << LL_ENDL;
|
||||
bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
|
||||
if ( fullRig )
|
||||
{
|
||||
|
|
@ -6610,6 +6665,10 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << "failed to add attachment overrides for root object " << root_object->getID() << " not mesh or no pSkinData" << LL_ENDL;
|
||||
}
|
||||
|
||||
//Rebuild body data if we altered joints/pelvis
|
||||
if ( pelvisGotSet )
|
||||
|
|
@ -9996,6 +10055,7 @@ void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
|
|||
LLViewerObject::updateRegion(regionp);
|
||||
}
|
||||
|
||||
// virtual
|
||||
std::string LLVOAvatar::getFullname() const
|
||||
{
|
||||
std::string name;
|
||||
|
|
@ -10318,14 +10378,11 @@ void LLVOAvatar::accountRenderComplexityForObject(
|
|||
const F32 max_attachment_complexity,
|
||||
LLVOVolume::texture_cost_t& textures,
|
||||
U32& cost,
|
||||
hud_complexity_list_t& hud_complexity_list)
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
std::map<LLUUID, U32> item_complexity;
|
||||
std::map<LLUUID, U32> temp_item_complexity;
|
||||
U32 body_parts_complexity;
|
||||
// </FS:Ansariel>
|
||||
|
||||
body_parts_complexity = cost; // <FS:Ansariel> Show per-item complexity in COF
|
||||
hud_complexity_list_t& hud_complexity_list,
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
std::map<LLUUID, U32>& item_complexity,
|
||||
std::map<LLUUID, U32>& temp_item_complexity)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
if (attached_object && !attached_object->isHUDAttachment())
|
||||
{
|
||||
|
|
@ -10384,19 +10441,19 @@ void LLVOAvatar::accountRenderComplexityForObject(
|
|||
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
|
||||
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
|
||||
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
if (isSelf())
|
||||
{
|
||||
if (!attached_object->isTempAttachment())
|
||||
{
|
||||
item_complexity.insert(std::make_pair(attached_object->getAttachmentItemID(), (U32)attachment_total_cost));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_item_complexity.insert(std::make_pair(attached_object->getID(), (U32)attachment_total_cost));
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
if (isSelf())
|
||||
{
|
||||
if (!attached_object->isTempAttachment())
|
||||
{
|
||||
item_complexity.insert(std::make_pair(attached_object->getAttachmentItemID(), (U32)attachment_total_cost));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_item_complexity.insert(std::make_pair(attached_object->getID(), (U32)attachment_total_cost));
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10481,6 +10538,12 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
|
||||
if (mVisualComplexityStale)
|
||||
{
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
std::map<LLUUID, U32> item_complexity;
|
||||
std::map<LLUUID, U32> temp_item_complexity;
|
||||
U32 body_parts_complexity;
|
||||
// </FS:Ansariel>
|
||||
|
||||
U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
|
||||
LLVOVolume::texture_cost_t textures;
|
||||
hud_complexity_list_t hud_complexity_list;
|
||||
|
|
@ -10499,6 +10562,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
}
|
||||
}
|
||||
LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
|
||||
body_parts_complexity = cost; // <FS:Ansariel> Show per-item complexity in COF
|
||||
|
||||
mAttachmentVisibleTriangleCount = 0;
|
||||
mAttachmentEstTriangleCount = 0.f;
|
||||
|
|
@ -10514,7 +10578,10 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
if (volp && !volp->isAttachment())
|
||||
{
|
||||
accountRenderComplexityForObject(volp, max_attachment_complexity,
|
||||
textures, cost, hud_complexity_list);
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
//textures, cost, hud_complexity_list);
|
||||
textures, cost, hud_complexity_list, item_complexity, temp_item_complexity);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10538,7 +10605,10 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
{
|
||||
const LLViewerObject* attached_object = (*attachment_iter);
|
||||
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
|
||||
textures, cost, hud_complexity_list);
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
//textures, cost, hud_complexity_list);
|
||||
textures, cost, hud_complexity_list, item_complexity, temp_item_complexity);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10611,12 +10681,12 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Show avatar complexity in appearance floater
|
||||
if (isSelf())
|
||||
{
|
||||
LLSidepanelAppearance::updateAvatarComplexity(mVisualComplexity, item_complexity, temp_item_complexity, body_parts_complexity);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> Show avatar complexity in appearance floater
|
||||
if (isSelf())
|
||||
{
|
||||
LLSidepanelAppearance::updateAvatarComplexity(mVisualComplexity, item_complexity, temp_item_complexity, body_parts_complexity);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,8 @@ private: //aligned members
|
|||
// Updates
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void updateAppearanceMessageDebugText();
|
||||
void updateAnimationDebugText();
|
||||
virtual void updateDebugText();
|
||||
virtual BOOL updateCharacter(LLAgent &agent);
|
||||
void updateFootstepSounds();
|
||||
|
|
@ -286,7 +288,11 @@ public:
|
|||
const F32 max_attachment_complexity,
|
||||
LLVOVolume::texture_cost_t& textures,
|
||||
U32& cost,
|
||||
hud_complexity_list_t& hud_complexity_list);
|
||||
hud_complexity_list_t& hud_complexity_list,
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
std::map<LLUUID, U32>& item_complexity,
|
||||
std::map<LLUUID, U32>& temp_item_complexity);
|
||||
// </FS:Ansariel>
|
||||
void calculateUpdateRenderComplexity();
|
||||
static const U32 VISUAL_COMPLEXITY_UNKNOWN;
|
||||
void updateVisualComplexity();
|
||||
|
|
@ -961,7 +967,7 @@ private:
|
|||
**/
|
||||
|
||||
public:
|
||||
std::string getFullname() const; // Returns "FirstName LastName"
|
||||
virtual std::string getFullname() const; // Returns "FirstName LastName"
|
||||
std::string avString() const; // Frequently used string in log messages "Avatar '<full name'"
|
||||
protected:
|
||||
static void getAnimLabels(std::vector<std::string>* labels);
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@
|
|||
#include "llanimationstates.h"
|
||||
#include "llinventorytype.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llcallstack.h"
|
||||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
#include "rlvactions.h"
|
||||
#include "rlvlocks.h"
|
||||
|
|
@ -323,6 +324,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
U32 block_num, EObjectUpdateType update_type,
|
||||
LLDataPacker *dp)
|
||||
{
|
||||
|
||||
LLColor4U color;
|
||||
const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
|
||||
|
||||
|
|
@ -336,6 +338,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
|
||||
sculpt_id = sculpt_params->getSculptTexture();
|
||||
sculpt_type = sculpt_params->getSculptType();
|
||||
|
||||
LL_DEBUGS("ObjectUpdate") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
}
|
||||
|
||||
if (!dp)
|
||||
|
|
@ -1516,7 +1521,7 @@ BOOL LLVOVolume::updateLOD()
|
|||
{
|
||||
if (isAnimatedObject() && isRiggedMesh())
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%u", (uintptr_t) this);
|
||||
std::string vobj_name = llformat("Vol%p", this);
|
||||
F32 est_tris = getEstTrianglesMax();
|
||||
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " updateLOD to " << getLOD() << ", tris " << est_tris << LL_ENDL;
|
||||
}
|
||||
|
|
@ -1610,7 +1615,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent)
|
|||
gPipeline.markMoved(mDrawable);
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
|
||||
}
|
||||
updateAnimatedObjectStateOnReparent(old_parent, parent);
|
||||
onReparent(old_parent, parent);
|
||||
}
|
||||
|
||||
return ret ;
|
||||
|
|
@ -3587,7 +3592,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags)
|
|||
param_block->setFlags(flags);
|
||||
}
|
||||
parameterChanged(LLNetworkData::PARAMS_EXTENDED_MESH, true);
|
||||
LL_DEBUGS("AnimatedObjects") << (uintptr_t) this
|
||||
LL_DEBUGS("AnimatedObjects") << this
|
||||
<< " new flags " << flags << " curr_flags " << curr_flags
|
||||
<< ", calling onSetExtendedMeshFlags()"
|
||||
<< LL_ENDL;
|
||||
|
|
@ -3614,8 +3619,10 @@ bool LLVOVolume::isAnimatedObject() const
|
|||
|
||||
// Called any time parenting changes for a volume. Update flags and
|
||||
// control av accordingly. This is called after parent has been
|
||||
// changed to new_parent.
|
||||
void LLVOVolume::updateAnimatedObjectStateOnReparent(LLViewerObject *old_parent, LLViewerObject *new_parent)
|
||||
// changed to new_parent, but before new_parent's mChildList has changed.
|
||||
|
||||
// virtual
|
||||
void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent)
|
||||
{
|
||||
LLVOVolume *old_volp = dynamic_cast<LLVOVolume*>(old_parent);
|
||||
|
||||
|
|
@ -3629,11 +3636,6 @@ void LLVOVolume::updateAnimatedObjectStateOnReparent(LLViewerObject *old_parent,
|
|||
mControlAvatar = NULL;
|
||||
av->markForDeath();
|
||||
}
|
||||
// If this succeeds now, it's because the new_parent is an animated object
|
||||
if (isAnimatedObject() && getControlAvatar())
|
||||
{
|
||||
getControlAvatar()->addAttachmentOverridesForObject(this);
|
||||
}
|
||||
}
|
||||
if (old_volp && old_volp->isAnimatedObject())
|
||||
{
|
||||
|
|
@ -3641,10 +3643,46 @@ void LLVOVolume::updateAnimatedObjectStateOnReparent(LLViewerObject *old_parent,
|
|||
{
|
||||
// We have been removed from an animated object, need to do cleanup.
|
||||
old_volp->getControlAvatar()->rebuildAttachmentOverrides();
|
||||
old_volp->getControlAvatar()->updateAnimations();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This needs to be called after onReparent(), because mChildList is
|
||||
// not updated until the end of LLViewerObject::addChild()
|
||||
|
||||
// virtual
|
||||
void LLVOVolume::afterReparent()
|
||||
{
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << "new child added for parent "
|
||||
<< ((LLViewerObject*)getParent())->getID() << LL_ENDL;
|
||||
}
|
||||
|
||||
if (isAnimatedObject() && getControlAvatar())
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object "
|
||||
<< ((LLViewerObject*)getParent())->getID() << LL_ENDL;
|
||||
|
||||
// MAINT-8239 - doing a full rebuild whenever parent is set
|
||||
// makes the joint overrides load more robustly. In theory,
|
||||
// addAttachmentOverrides should be sufficient, but in
|
||||
// practice doing a full rebuild helps compensate for
|
||||
// notifyMeshLoaded() not being called reliably enough.
|
||||
|
||||
// was: getControlAvatar()->addAttachmentOverridesForObject(this);
|
||||
getControlAvatar()->rebuildAttachmentOverrides();
|
||||
getControlAvatar()->updateAnimations();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: "
|
||||
<< ((LLViewerObject*)getParent())->getID()
|
||||
<< " isAnimated: " << isAnimatedObject() << " cav "
|
||||
<< getControlAvatar() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
|
||||
|
|
@ -4146,7 +4184,7 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
|
|||
bool was_enabled = (getControlAvatar() != NULL);
|
||||
if (enabled != was_enabled)
|
||||
{
|
||||
LL_DEBUGS("AnimatedObjects") << (uintptr_t) this
|
||||
LL_DEBUGS("AnimatedObjects") << this
|
||||
<< " calling onSetExtendedMeshFlags, enabled " << (U32) enabled
|
||||
<< " was_enabled " << (U32) was_enabled
|
||||
<< " local_origin " << (U32) local_origin
|
||||
|
|
@ -4305,7 +4343,7 @@ void LLVOVolume::markForUpdate(BOOL priority)
|
|||
{
|
||||
if (isAnimatedObject() && isRiggedMesh())
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%u", (uintptr_t) this);
|
||||
std::string vobj_name = llformat("Vol%p", this);
|
||||
F32 est_tris = getEstTrianglesMax();
|
||||
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markForUpdate, tris " << est_tris << LL_ENDL;
|
||||
}
|
||||
|
|
@ -5290,7 +5328,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string vobj_name = llformat("Vol%u", (uintptr_t) vobj);
|
||||
std::string vobj_name = llformat("Vol%p", vobj);
|
||||
|
||||
if (vobj->isMesh() &&
|
||||
((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
|
||||
|
|
@ -5852,7 +5890,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
|||
{
|
||||
if (vobj->isAnimatedObject() && vobj->isRiggedMesh())
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%u", (U32) vobj);
|
||||
std::string vobj_name = llformat("Vol%p", vobj);
|
||||
F32 est_tris = vobj->getEstTrianglesMax();
|
||||
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,7 +281,8 @@ public:
|
|||
void setExtendedMeshFlags(U32 flags);
|
||||
bool canBeAnimatedObject() const;
|
||||
bool isAnimatedObject() const;
|
||||
void updateAnimatedObjectStateOnReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
|
||||
virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
|
||||
virtual void afterReparent();
|
||||
|
||||
std::map<LLUUID, S32> mObjectSignaledAnimations; // requested state of Animation name/value
|
||||
|
||||
|
|
|
|||
|
|
@ -3460,7 +3460,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
|
|||
LLVOVolume *vol_obj = drawablep->getVOVolume();
|
||||
if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh())
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%u", (uintptr_t) vol_obj);
|
||||
std::string vobj_name = llformat("Vol%p", vol_obj);
|
||||
F32 est_tris = vol_obj->getEstTrianglesMax();
|
||||
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markRebuild, tris " << est_tris
|
||||
<< " priority " << (S32) priority << " flag " << std::hex << flag << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -363,4 +363,20 @@
|
|||
<menu_item_call.on_enable
|
||||
function="EnableMuteParticle" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Dump XML"
|
||||
name="Dump XML">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.AppearanceToXML" />
|
||||
<menu_item_call.on_visible
|
||||
function="Advanced.EnableAppearanceToXML"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Reset Skeleton"
|
||||
name="Reset Skeleton">
|
||||
<menu_item_call.on_click
|
||||
function="Avatar.ResetSkeleton" />
|
||||
<menu_item_call.on_visible
|
||||
function="Advanced.EnableResetSkeleton"/>
|
||||
</menu_item_call>
|
||||
</context_menu>
|
||||
|
|
|
|||
Loading…
Reference in New Issue