diff --git a/etc/message.xml b/etc/message.xml
index 427a6ac40..ea6fc8146 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -663,7 +663,7 @@
false
RequestTextureDownload
- false
+ true
EventQueueGet
false
@@ -715,6 +715,9 @@
FetchLib2
true
+
+ UploadBakedTexture
+ true
messageBans
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 4053ad9b0..d5708ac45 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -48,6 +48,7 @@ add_custom_target(prepare DEPENDS ${prepare_depends})
add_subdirectory(cmake)
add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine)
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
+add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 916da75d0..20ffa15cd 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -42,6 +42,7 @@ set(cmake_SOURCE_FILES
Hunspell.cmake
JPEG.cmake
LLAddBuildTest.cmake
+ LLAppearance.cmake
LLAudio.cmake
LLCharacter.cmake
LLCommon.cmake
diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake
new file mode 100644
index 000000000..ba0274a65
--- /dev/null
+++ b/indra/cmake/LLAppearance.cmake
@@ -0,0 +1,11 @@
+# -*- cmake -*-
+
+include(Variables)
+
+set(LLAPPEARANCE_INCLUDE_DIRS
+ ${LIBS_OPEN_DIR}/llappearance
+ )
+
+set(LLAPPEARANCE_LIBRARIES llappearance)
+
+
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
new file mode 100644
index 000000000..51db4c927
--- /dev/null
+++ b/indra/llappearance/CMakeLists.txt
@@ -0,0 +1,89 @@
+# -*- cmake -*-
+
+project(llappearance)
+
+include(00-Common)
+include(LLCommon)
+include(LLCharacter)
+include(LLImage)
+include(LLInventory)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLVFS)
+include(LLWindow)
+include(LLXML)
+include(Linking)
+
+include_directories(
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLCHARACTER_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLINVENTORY_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLVFS_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ )
+
+set(llappearance_SOURCE_FILES
+ llavatarappearance.cpp
+ llavatarjoint.cpp
+ llavatarjointmesh.cpp
+ lldriverparam.cpp
+ lllocaltextureobject.cpp
+ llpolyskeletaldistortion.cpp
+ llpolymesh.cpp
+ llpolymorph.cpp
+ lltexglobalcolor.cpp
+ lltexlayer.cpp
+ lltexlayerparams.cpp
+ lltexturemanagerbridge.cpp
+ llwearable.cpp
+ llwearabledata.cpp
+ llwearabletype.cpp
+ llviewervisualparam.cpp
+ llavatarappearancedefines.cpp
+ )
+
+set(llappearance_HEADER_FILES
+ CMakeLists.txt
+
+ llavatarappearance.h
+ llavatarjoint.h
+ llavatarjointmesh.h
+ lldriverparam.h
+ lljointpickname.h
+ lllocaltextureobject.h
+ llpolyskeletaldistortion.h
+ llpolymesh.h
+ llpolymorph.h
+ lltexglobalcolor.h
+ lltexlayer.h
+ lltexlayerparams.h
+ lltexturemanagerbridge.h
+ llwearable.h
+ llwearabledata.h
+ llwearabletype.h
+ llviewervisualparam.h
+ llavatarappearancedefines.h
+ )
+
+set_source_files_properties(${llappearance_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
+
+add_library (llappearance ${llappearance_SOURCE_FILES})
+
+target_link_libraries(llappearance
+ ${LLCHARACTER_LIBRARIES}
+ ${LLINVENTORY_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLRENDER_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ )
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
new file mode 100644
index 000000000..d186ce79b
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -0,0 +1,2020 @@
+/**
+ * @File llavatarappearance.cpp
+ * @brief Implementation of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#if LL_MSVC
+// disable warning about boost::lexical_cast returning uninitialized data
+// when it fails to parse the string
+#pragma warning (disable:4701)
+#endif
+
+#include "linden_common.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "imageids.h"
+#include "lldir.h"
+#include "lldeleteutils.h"
+#include "llpolymorph.h"
+#include "llpolymesh.h"
+#include "llpolyskeletaldistortion.h"
+#include "llstl.h"
+#include "lltexglobalcolor.h"
+#include "llwearabledata.h"
+
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include
+
+using namespace LLAvatarAppearanceDefines;
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const std::string AVATAR_DEFAULT_CHAR = "avatar";
+const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
+
+/*********************************************************************************
+ ** **
+ ** Begin private LLAvatarAppearance Support classes
+ **
+ **/
+
+//------------------------------------------------------------------------
+// LLAvatarBoneInfo
+// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton.
+//------------------------------------------------------------------------
+class LLAvatarBoneInfo
+{
+ friend class LLAvatarAppearance;
+ friend class LLAvatarSkeletonInfo;
+public:
+ LLAvatarBoneInfo() : mIsJoint(FALSE) {}
+ ~LLAvatarBoneInfo()
+ {
+ std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
+ }
+ BOOL parseXml(LLXmlTreeNode* node);
+
+private:
+ std::string mName;
+ BOOL mIsJoint;
+ LLVector3 mPos;
+ LLVector3 mRot;
+ LLVector3 mScale;
+ LLVector3 mPivot;
+ typedef std::vector child_list_t;
+ child_list_t mChildList;
+};
+
+//------------------------------------------------------------------------
+// LLAvatarSkeletonInfo
+// Overall avatar skeleton
+//------------------------------------------------------------------------
+class LLAvatarSkeletonInfo
+{
+ friend class LLAvatarAppearance;
+public:
+ LLAvatarSkeletonInfo() :
+ mNumBones(0), mNumCollisionVolumes(0) {}
+ ~LLAvatarSkeletonInfo()
+ {
+ std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
+ }
+ BOOL parseXml(LLXmlTreeNode* node);
+ S32 getNumBones() const { return mNumBones; }
+ S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+
+private:
+ S32 mNumBones;
+ S32 mNumCollisionVolumes;
+ typedef std::vector bone_info_list_t;
+ bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLAvatarXmlInfo
+//-----------------------------------------------------------------------------
+
+LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo()
+ : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
+{
+}
+
+LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
+{
+ std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
+ std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());
+ std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
+ deleteAndClear(mTexSkinColorInfo);
+ deleteAndClear(mTexHairColorInfo);
+ deleteAndClear(mTexEyeColorInfo);
+ std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
+ std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+ std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
+}
+
+
+/**
+ **
+ ** End LLAvatarAppearance Support classes
+ ** **
+ *********************************************************************************/
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+LLXmlTree LLAvatarAppearance::sXMLTree;
+LLXmlTree LLAvatarAppearance::sSkeletonXMLTree;
+LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL;
+LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL;
+
+
+LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
+ LLCharacter(),
+ mIsDummy(FALSE),
+ mTexSkinColor( NULL ),
+ mTexHairColor( NULL ),
+ mTexEyeColor( NULL ),
+ mPelvisToFoot(0.f),
+ mHeadOffset(),
+ mRoot(NULL),
+ mWearableData(wearable_data)
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ llassert_always(mWearableData);
+ mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
+ {
+ mBakedTextureDatas[i].mLastTextureID = IMG_DEFAULT_AVATAR;
+ mBakedTextureDatas[i].mTexLayerSet = NULL;
+ mBakedTextureDatas[i].mIsLoaded = false;
+ mBakedTextureDatas[i].mIsUsed = false;
+ mBakedTextureDatas[i].mMaskTexName = 0;
+ mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
+ }
+
+ mIsBuilt = FALSE;
+
+ mNumCollisionVolumes = 0;
+ mCollisionVolumes = NULL;
+}
+
+// virtual
+void LLAvatarAppearance::initInstance()
+{
+ //-------------------------------------------------------------------------
+ // initialize joint, mesh and shape members
+ //-------------------------------------------------------------------------
+ mRoot = createAvatarJoint();
+ mRoot->setName( "mRoot" );
+
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++iter)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+ LLAvatarJoint* joint = createAvatarJoint();
+ joint->setName(mesh_dict->mName);
+ joint->setMeshID(mesh_index);
+ mMeshLOD.push_back(joint);
+
+ /* mHairLOD.setName("mHairLOD");
+ mHairMesh0.setName("mHairMesh0");
+ mHairMesh0.setMeshID(MESH_ID_HAIR);
+ mHairMesh1.setName("mHairMesh1"); */
+ for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
+ {
+ LLAvatarJointMesh* mesh = createAvatarJointMesh();
+ std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast(lod);
+ // We pre-pended an m - need to capitalize first character for camelCase
+ mesh_name[1] = toupper(mesh_name[1]);
+ mesh->setName(mesh_name);
+ mesh->setMeshID(mesh_index);
+ mesh->setPickName(mesh_dict->mPickName);
+ mesh->setIsTransparent(FALSE);
+ switch((int)mesh_index)
+ {
+ case MESH_ID_HAIR:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_SKIRT:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_EYEBALL_LEFT:
+ case MESH_ID_EYEBALL_RIGHT:
+ mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
+ break;
+ }
+
+ joint->mMeshParts.push_back(mesh);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // associate baked textures with meshes
+ //-------------------------------------------------------------------------
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++iter)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+ const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
+ // Skip it if there's no associated baked texture.
+ if (baked_texture_index == BAKED_NUM_INDICES) continue;
+
+ for (avatar_joint_mesh_list_t::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
+ iter != mMeshLOD[mesh_index]->mMeshParts.end();
+ ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ mBakedTextureDatas[(int)baked_texture_index].mJointMeshes.push_back(mesh);
+ }
+ }
+
+ if (gNoRender)
+ {
+ return;
+ }
+ buildCharacter();
+
+}
+
+// virtual
+LLAvatarAppearance::~LLAvatarAppearance()
+{
+ deleteAndClear(mTexSkinColor);
+ deleteAndClear(mTexHairColor);
+ deleteAndClear(mTexEyeColor);
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
+ mBakedTextureDatas[i].mJointMeshes.clear();
+
+ for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
+ iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
+ {
+ LLMaskedMorph* masked_morph = (*iter2);
+ delete masked_morph;
+ }
+ }
+
+ if (mRoot) mRoot->removeAllChildren();
+ deleteAndClear(mRoot);
+ mJointMap.clear();
+
+ clearSkeleton();
+ deleteAndClearArray(mCollisionVolumes);
+
+ std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
+ mPolyMeshes.clear();
+
+ for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+ jointIter != mMeshLOD.end();
+ ++jointIter)
+ {
+ LLAvatarJoint* joint = *jointIter;
+ std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
+ joint->mMeshParts.clear();
+ }
+ std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
+ mMeshLOD.clear();
+}
+
+//static
+void LLAvatarAppearance::initClass()
+{
+ std::string xmlFile;
+
+ xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
+ BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
+ if (!success)
+ {
+ llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
+ }
+
+ // now sanity check xml file
+ LLXmlTreeNode* root = sXMLTree.getRoot();
+ if (!root)
+ {
+ llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ // (root)
+ //-------------------------------------------------------------------------
+ if( !root->hasName( "linden_avatar" ) )
+ {
+ llerrs << "Invalid avatar file header: " << xmlFile << llendl;
+ }
+
+ std::string version;
+ static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+ if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+ {
+ llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
+ }
+
+ S32 wearable_def_version = 1;
+ static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
+ root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
+ LLWearable::setCurrentDefinitionVersion( wearable_def_version );
+
+ std::string mesh_file_name;
+
+ LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
+ if (!skeleton_node)
+ {
+ llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
+ return;
+ }
+
+ std::string skeleton_file_name;
+ static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+ if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
+ {
+ llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
+ }
+
+ std::string skeleton_path;
+ skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
+ if (!parseSkeletonFile(skeleton_path))
+ {
+ llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
+ }
+
+ // Process XML data
+
+ // avatar_skeleton.xml
+ if (sAvatarSkeletonInfo)
+ { //this can happen if a login attempt failed
+ delete sAvatarSkeletonInfo;
+ }
+ sAvatarSkeletonInfo = new LLAvatarSkeletonInfo;
+ if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
+ {
+ llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
+ }
+ // parse avatar_lad.xml
+ if (sAvatarXmlInfo)
+ { //this can happen if a login attempt failed
+ deleteAndClear(sAvatarXmlInfo);
+ }
+ sAvatarXmlInfo = new LLAvatarXmlInfo;
+ if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlColorNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+}
+
+void LLAvatarAppearance::cleanupClass()
+{
+ deleteAndClear(sAvatarXmlInfo);
+ deleteAndClear(sAvatarSkeletonInfo);
+ sSkeletonXMLTree.cleanup();
+ sXMLTree.cleanup();
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+//------------------------------------------------------------------------
+// The viewer can only suggest a good size for the agent,
+// the simulator will keep it inside a reasonable range.
+void LLAvatarAppearance::computeBodySize()
+{
+ LLVector3 pelvis_scale = mPelvisp->getScale();
+
+ // some of the joints have not been cached
+ LLVector3 skull = mSkullp->getPosition();
+ //LLVector3 skull_scale = mSkullp->getScale();
+
+ LLVector3 neck = mNeckp->getPosition();
+ LLVector3 neck_scale = mNeckp->getScale();
+
+ LLVector3 chest = mChestp->getPosition();
+ LLVector3 chest_scale = mChestp->getScale();
+
+ // the rest of the joints have been cached
+ LLVector3 head = mHeadp->getPosition();
+ LLVector3 head_scale = mHeadp->getScale();
+
+ LLVector3 torso = mTorsop->getPosition();
+ LLVector3 torso_scale = mTorsop->getScale();
+
+ LLVector3 hip = mHipLeftp->getPosition();
+ LLVector3 hip_scale = mHipLeftp->getScale();
+
+ LLVector3 knee = mKneeLeftp->getPosition();
+ LLVector3 knee_scale = mKneeLeftp->getScale();
+
+ LLVector3 ankle = mAnkleLeftp->getPosition();
+ LLVector3 ankle_scale = mAnkleLeftp->getScale();
+
+ LLVector3 foot = mFootLeftp->getPosition();
+
+ mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
+ knee.mV[VZ] * hip_scale.mV[VZ] -
+ ankle.mV[VZ] * knee_scale.mV[VZ] -
+ foot.mV[VZ] * ankle_scale.mV[VZ];
+
+ LLVector3 new_body_size;
+ new_body_size.mV[VZ] = mPelvisToFoot +
+ // the sqrt(2) correction below is an approximate
+ // correction to get to the top of the head
+ F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
+ head.mV[VZ] * neck_scale.mV[VZ] +
+ neck.mV[VZ] * chest_scale.mV[VZ] +
+ chest.mV[VZ] * torso_scale.mV[VZ] +
+ torso.mV[VZ] * pelvis_scale.mV[VZ];
+
+ // TODO -- measure the real depth and width
+ new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
+ new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
+
+ if (new_body_size != mBodySize)
+ {
+ mBodySize = new_body_size;
+ bodySizeChanged();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// parseSkeletonFile()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ //-------------------------------------------------------------------------
+ // parse the file
+ //-------------------------------------------------------------------------
+ BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+
+ if (!parsesuccess)
+ {
+ llerrs << "Can't parse skeleton file: " << filename << llendl;
+ return FALSE;
+ }
+
+ // now sanity check xml file
+ LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
+ if (!root)
+ {
+ llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
+ return FALSE;
+ }
+
+ if( !root->hasName( "linden_skeleton" ) )
+ {
+ llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
+ return FALSE;
+ }
+
+ std::string version;
+ static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+ if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+ {
+ llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// setupBone()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &volume_num, S32 &joint_num)
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ LLJoint* joint = NULL;
+
+ if (info->mIsJoint)
+ {
+ joint = getCharacterJoint(joint_num);
+ if (!joint)
+ {
+ llwarns << "Too many bones" << llendl;
+ return FALSE;
+ }
+ joint->setName( info->mName );
+ }
+ else // collision volume
+ {
+ if (volume_num >= (S32)mNumCollisionVolumes)
+ {
+ llwarns << "Too many bones" << llendl;
+ return FALSE;
+ }
+ joint = (&mCollisionVolumes[volume_num]);
+ joint->setName( info->mName );
+ }
+
+ // add to parent
+ if (parent)
+ {
+ parent->addChild( joint );
+ }
+
+ joint->setPosition(info->mPos);
+ joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
+ info->mRot.mV[VZ], LLQuaternion::XYZ));
+ joint->setScale(info->mScale);
+
+ joint->setDefaultFromCurrentXform();
+
+ if (info->mIsJoint)
+ {
+ joint->setSkinOffset( info->mPivot );
+ joint_num++;
+ }
+ else // collision volume
+ {
+ volume_num++;
+ }
+
+ // setup children
+ LLAvatarBoneInfo::child_list_t::const_iterator iter;
+ for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
+ {
+ LLAvatarBoneInfo *child_info = *iter;
+ if (!setupBone(child_info, joint, volume_num, joint_num))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCharacterJoints()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
+{
+ clearSkeleton();
+
+ for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
+ {
+ mSkeleton.push_back(createAvatarJoint(joint_num));
+ }
+
+
+ if (mSkeleton.empty() || !mSkeleton[0])
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// buildSkeleton()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+
+ if (!info)
+ return FALSE;
+ //-------------------------------------------------------------------------
+ // allocate joints
+ //-------------------------------------------------------------------------
+ if (!allocateCharacterJoints(info->mNumBones))
+ {
+ llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+ return FALSE;
+ }
+
+ //-------------------------------------------------------------------------
+ // allocate volumes
+ //-------------------------------------------------------------------------
+ if (info->mNumCollisionVolumes)
+ {
+ if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+ {
+ llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+ return FALSE;
+ }
+ }
+
+ S32 current_joint_num = 0;
+ S32 current_volume_num = 0;
+ LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
+ for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+ {
+ LLAvatarBoneInfo *info = *iter;
+ if (!setupBone(info, NULL, current_volume_num, current_joint_num))
+ {
+ llerrs << "Error parsing bone in skeleton file" << llendl;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// clearSkeleton()
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::clearSkeleton()
+{
+ std::for_each(mSkeleton.begin(), mSkeleton.end(), DeletePointer());
+ mSkeleton.clear();
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::buildCharacter()
+// Deferred initialization and rebuild of the avatar.
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::buildCharacter()
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ //-------------------------------------------------------------------------
+ // remove all references to our existing skeleton
+ // so we can rebuild it
+ //-------------------------------------------------------------------------
+ flushAllMotions();
+
+ //-------------------------------------------------------------------------
+ // remove all of mRoot's children
+ //-------------------------------------------------------------------------
+ mRoot->removeAllChildren();
+ mJointMap.clear();
+ mIsBuilt = FALSE;
+
+ //-------------------------------------------------------------------------
+ // clear mesh data
+ //-------------------------------------------------------------------------
+ for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+ jointIter != mMeshLOD.end(); ++jointIter)
+ {
+ LLAvatarJoint* joint = *jointIter;
+ for (avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+ meshIter != joint->mMeshParts.end(); ++meshIter)
+ {
+ LLAvatarJointMesh * mesh = *meshIter;
+ mesh->setMesh(NULL);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // (re)load our skeleton and meshes
+ //-------------------------------------------------------------------------
+ LLTimer timer;
+
+ BOOL status = loadAvatar();
+ stop_glerror();
+
+ if (gNoRender)
+ {
+ // Still want to load the avatar skeleton so visual parameters work.
+ return;
+ }
+
+// gPrintMessagesThisFrame = TRUE;
+ lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
+
+ if (!status)
+ {
+ if (isSelf())
+ {
+ llerrs << "Unable to load user's avatar" << llendl;
+ }
+ else
+ {
+ llwarns << "Unable to load other's avatar" << llendl;
+ }
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ // initialize "well known" joint pointers
+ //-------------------------------------------------------------------------
+ mPelvisp = mRoot->findJoint("mPelvis");
+ mTorsop = mRoot->findJoint("mTorso");
+ mChestp = mRoot->findJoint("mChest");
+ mNeckp = mRoot->findJoint("mNeck");
+ mHeadp = mRoot->findJoint("mHead");
+ mSkullp = mRoot->findJoint("mSkull");
+ mHipLeftp = mRoot->findJoint("mHipLeft");
+ mHipRightp = mRoot->findJoint("mHipRight");
+ mKneeLeftp = mRoot->findJoint("mKneeLeft");
+ mKneeRightp = mRoot->findJoint("mKneeRight");
+ mAnkleLeftp = mRoot->findJoint("mAnkleLeft");
+ mAnkleRightp = mRoot->findJoint("mAnkleRight");
+ mFootLeftp = mRoot->findJoint("mFootLeft");
+ mFootRightp = mRoot->findJoint("mFootRight");
+ mWristLeftp = mRoot->findJoint("mWristLeft");
+ mWristRightp = mRoot->findJoint("mWristRight");
+ mEyeLeftp = mRoot->findJoint("mEyeLeft");
+ mEyeRightp = mRoot->findJoint("mEyeRight");
+
+ //-------------------------------------------------------------------------
+ // Make sure "well known" pointers exist
+ //-------------------------------------------------------------------------
+ if (!(mPelvisp &&
+ mTorsop &&
+ mChestp &&
+ mNeckp &&
+ mHeadp &&
+ mSkullp &&
+ mHipLeftp &&
+ mHipRightp &&
+ mKneeLeftp &&
+ mKneeRightp &&
+ mAnkleLeftp &&
+ mAnkleRightp &&
+ mFootLeftp &&
+ mFootRightp &&
+ mWristLeftp &&
+ mWristRightp &&
+ mEyeLeftp &&
+ mEyeRightp))
+ {
+ llerrs << "Failed to create avatar." << llendl;
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ // initialize the pelvis
+ //-------------------------------------------------------------------------
+ mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
+
+ mIsBuilt = TRUE;
+ stop_glerror();
+
+}
+
+//-----------------------------------------------------------------------------
+// loadAvatar()
+//-----------------------------------------------------------------------------
+//static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar");
+
+BOOL LLAvatarAppearance::loadAvatar()
+{
+// LLFastTimer t(FTM_LOAD_AVATAR);
+
+ // avatar_skeleton.xml
+ if( !buildSkeleton(sAvatarSkeletonInfo) )
+ {
+ llwarns << "avatar file: buildSkeleton() failed" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml :
+ if( !loadSkeletonNode() )
+ {
+ llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml :
+ if( !loadMeshNodes() )
+ {
+ llwarns << "avatar file: loadNodeMesh() failed" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml :
+ if( sAvatarXmlInfo->mTexSkinColorInfo )
+ {
+ mTexSkinColor = new LLTexGlobalColor( this );
+ if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
+ {
+ llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << " name=\"skin_color\" not found" << llendl;
+ return FALSE;
+ }
+ if( sAvatarXmlInfo->mTexHairColorInfo )
+ {
+ mTexHairColor = new LLTexGlobalColor( this );
+ if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
+ {
+ llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << " name=\"hair_color\" not found" << llendl;
+ return FALSE;
+ }
+ if( sAvatarXmlInfo->mTexEyeColorInfo )
+ {
+ mTexEyeColor = new LLTexGlobalColor( this );
+ if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
+ {
+ llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << " name=\"eye_color\" not found" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml :
+ if (sAvatarXmlInfo->mLayerInfoList.empty())
+ {
+ llwarns << "avatar file: missing node" << llendl;
+ return FALSE;
+ }
+
+ if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
+ {
+ llwarns << "avatar file: missing node" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml :
+ for (LLAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
+ iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
+ ++iter)
+ {
+ LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter;
+
+ EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion);
+ if (baked != BAKED_NUM_INDICES)
+ {
+ LLVisualParam* morph_param;
+ const std::string *name = &info->mName;
+ morph_param = getVisualParam(name->c_str());
+ if (morph_param)
+ {
+ BOOL invert = info->mInvert;
+ addMaskedMorph(baked, morph_param, invert, info->mLayer);
+ }
+ }
+
+ }
+
+ loadLayersets();
+
+ // avatar_lad.xml :
+ for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+ iter != sAvatarXmlInfo->mDriverInfoList.end();
+ ++iter)
+ {
+ LLDriverParamInfo *info = *iter;
+ LLDriverParam* driver_param = new LLDriverParam( this );
+ if (driver_param->setInfo(info))
+ {
+ addVisualParam( driver_param );
+ driver_param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ LLVisualParam*(LLAvatarAppearance::*avatar_function)(S32)const = &LLAvatarAppearance::getVisualParam;
+ if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLAvatarAppearance*)this,_1 ), false))
+ {
+ llwarns << "could not link driven params for avatar " << this->getFullname() << " param id: " << driver_param->getID() << llendl;
+ continue;
+ }
+ }
+ else
+ {
+ delete driver_param;
+ llwarns << "avatar file: driver_param->parseData() failed" << llendl;
+ return FALSE;
+ }
+ }
+
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadSkeletonNode(): loads node from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadSkeletonNode ()
+{
+ mRoot->addChild( mSkeleton[0] );
+
+ // make meshes children before calling parent version of the function
+ for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
+ iter != mMeshLOD.end();
+ ++iter)
+ {
+ LLAvatarJoint *joint = *iter;
+ joint->mUpdateXform = FALSE;
+ joint->setMeshesToChildren();
+ }
+
+ mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+ mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]);
+ mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
+ mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
+ mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
+ mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+
+ LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull");
+ if (skull)
+ {
+ skull->addChild(mMeshLOD[MESH_ID_HAIR] );
+ }
+
+ LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft");
+ if (eyeL)
+ {
+ eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
+ }
+
+ LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight");
+ if (eyeR)
+ {
+ eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
+ }
+
+ // SKELETAL DISTORTIONS
+ {
+ LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
+ for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
+ iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
+ ++iter)
+ {
+ LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
+ LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
+ if (!param->setInfo(info))
+ {
+ delete param;
+ return FALSE;
+ }
+ else
+ {
+ addVisualParam(param);
+ param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+ }
+ }
+
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadMeshNodes(): loads nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadMeshNodes()
+{
+ for (LLAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
+ meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();
+ ++meshinfo_iter)
+ {
+ const LLAvatarXmlInfo::LLAvatarMeshInfo *info = *meshinfo_iter;
+ const std::string &type = info->mType;
+ S32 lod = info->mLOD;
+
+ LLAvatarJointMesh* mesh = NULL;
+ U8 mesh_id = 0;
+ BOOL found_mesh_id = FALSE;
+
+ /* if (type == "hairMesh")
+ switch(lod)
+ case 0:
+ mesh = &mHairMesh0; */
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++mesh_iter)
+ {
+ const EMeshIndex mesh_index = mesh_iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second;
+ if (type.compare(mesh_dict->mName) == 0)
+ {
+ mesh_id = mesh_index;
+ found_mesh_id = TRUE;
+ break;
+ }
+ }
+
+ if (found_mesh_id)
+ {
+ if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
+ {
+ mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
+ }
+ else
+ {
+ llwarns << "Avatar file: has invalid lod setting " << lod << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
+ return FALSE;
+ }
+
+ // llinfos << "Parsing mesh data for " << type << "..." << llendl;
+
+ // If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
+ // Do not touch!!!
+ mesh->setColor( LLColor4::white );
+
+ LLPolyMesh *poly_mesh = NULL;
+
+ if (!info->mReferenceMeshName.empty())
+ {
+ polymesh_map_t::const_iterator polymesh_iter = mPolyMeshes.find(info->mReferenceMeshName);
+ if (polymesh_iter != mPolyMeshes.end())
+ {
+ poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
+ poly_mesh->setAvatar(this);
+ }
+ else
+ {
+ // This should never happen
+ LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
+ }
+ }
+ else
+ {
+ poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
+ poly_mesh->setAvatar(this);
+ }
+
+ if( !poly_mesh )
+ {
+ llwarns << "Failed to load mesh of type " << type << llendl;
+ return FALSE;
+ }
+
+ // Multimap insert
+ mPolyMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
+
+ mesh->setMesh( poly_mesh );
+ mesh->setLOD( info->mMinPixelArea );
+
+ for (LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
+ xmlinfo_iter != info->mPolyMorphTargetInfoList.end();
+ ++xmlinfo_iter)
+ {
+ const LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
+ LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
+ if (!param->setInfo((LLPolyMorphTargetInfo*)info_pair->first))
+ {
+ delete param;
+ return FALSE;
+ }
+ else
+ {
+ if (info_pair->second)
+ {
+ addSharedVisualParam(param);
+ param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+ else
+ {
+ addVisualParam(param);
+ param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadLayerSets()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadLayersets()
+{
+ BOOL success = TRUE;
+ for (LLAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
+ layerset_iter != sAvatarXmlInfo->mLayerInfoList.end();
+ ++layerset_iter)
+ {
+ LLTexLayerSetInfo *layerset_info = *layerset_iter;
+ if (isSelf())
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSet* layer_set = createTexLayerSet();
+
+ if (!layer_set->setInfo(layerset_info))
+ {
+ stop_glerror();
+ delete layer_set;
+ llwarns << "avatar file: layer_set->setInfo() failed" << llendl;
+ return FALSE;
+ }
+
+ // scan baked textures and associate the layerset with the appropriate one
+ EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ if (layer_set->isBodyRegion(baked_dict->mName))
+ {
+ baked_index = baked_iter->first;
+ // ensure both structures are aware of each other
+ mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
+ layer_set->setBakedTexIndex(baked_index);
+ break;
+ }
+ }
+ // if no baked texture was found, warn and cleanup
+ if (baked_index == BAKED_NUM_INDICES)
+ {
+ llwarns << " has invalid body_region attribute" << llendl;
+ delete layer_set;
+ return FALSE;
+ }
+
+ // scan morph masks and let any affected layers know they have an associated morph
+ for (LLAvatarAppearance::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
+ morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
+ ++morph_iter)
+ {
+ LLMaskedMorph *morph = *morph_iter;
+ LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
+ if (layer)
+ {
+ layer->setHasMorph(TRUE);
+ }
+ else
+ {
+ llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
+ success = FALSE;
+ }
+ }
+ }
+ else // !isSelf()
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSetInfo *layerset_info = *layerset_iter;
+ layerset_info->createVisualParams(this);
+ }
+ }
+ return success;
+}
+
+//-----------------------------------------------------------------------------
+// getCharacterJoint()
+//-----------------------------------------------------------------------------
+LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num )
+{
+ if ((S32)num >= mSkeleton.size()
+ || (S32)num < 0)
+ {
+ return NULL;
+ }
+ return mSkeleton[num];
+}
+
+
+//-----------------------------------------------------------------------------
+// getVolumePos()
+//-----------------------------------------------------------------------------
+LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_offset)
+{
+ if(joint_index < 0)
+ {
+ return LLVector3::zero;
+ }
+
+ if (joint_index > mNumCollisionVolumes)
+ {
+ return LLVector3::zero;
+ }
+
+ return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
+{
+ //SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32
+ //to compare we also need to be sure of the wrap around case producing (S32) <0
+ //or in terms of the U32 an out of bounds index in the array.
+ if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0)
+ {
+ return NULL;
+ }
+
+ return &mCollisionVolumes[volume_id];
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name)
+{
+ for (S32 i = 0; i < mNumCollisionVolumes; i++)
+ {
+ if (mCollisionVolumes[i].getName() == name)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getHeadMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh* LLAvatarAppearance::getHeadMesh()
+{
+ return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getUpperBodyMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh* LLAvatarAppearance::getUpperBodyMesh()
+{
+ return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
+}
+
+
+//-----------------------------------------------------------------------------
+// getMesh( LLPolyMeshSharedData *shared_data )
+//-----------------------------------------------------------------------------
+LLPolyMesh* LLAvatarAppearance::getMesh( LLPolyMeshSharedData *shared_data )
+{
+ for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
+ {
+ LLPolyMesh* mesh = i->second;
+ if (mesh->getSharedData() == shared_data)
+ {
+ return mesh;
+ }
+ }
+ return NULL;
+}
+
+// static
+void LLAvatarAppearance::getMeshInfo (mesh_info_t* mesh_info)
+{
+ if (!mesh_info) return;
+
+ LLAvatarXmlInfo::mesh_info_list_t::iterator iter = sAvatarXmlInfo->mMeshInfoList.begin();
+ LLAvatarXmlInfo::mesh_info_list_t::iterator end = sAvatarXmlInfo->mMeshInfoList.end();
+
+ for (; iter != end; ++iter)
+ {
+ LLAvatarXmlInfo::LLAvatarMeshInfo* avatar_info = (*iter);
+ std::string type = avatar_info->mType;
+ S32 lod = avatar_info->mLOD;
+ std::string file = avatar_info->mMeshFileName;
+
+ mesh_info_t::iterator iter_info = mesh_info->find(type);
+ if(iter_info == mesh_info->end())
+ {
+ lod_mesh_map_t lod_mesh;
+ lod_mesh.insert(std::pair(lod, file));
+ mesh_info->insert(std::pair(type, lod_mesh));
+ }
+ else
+ {
+ lod_mesh_map_t& lod_mesh = iter_info->second;
+ lod_mesh_map_t::iterator iter_lod = lod_mesh.find(lod);
+ if (iter_lod == lod_mesh.end())
+ {
+ lod_mesh.insert(std::pair(lod, file));
+ }
+ else
+ {
+ // Should never happen
+ llwarns << "Duplicate mesh LOD " << type << " " << lod << " " << file << llendl;
+ }
+ }
+ }
+ return;
+}
+
+// virtual
+BOOL LLAvatarAppearance::isValid() const
+{
+ // This should only be called on ourself.
+ if (!isSelf())
+ {
+ llerrs << "Called LLAvatarAppearance::isValid() on when isSelf() == false" << llendl;
+ }
+ return TRUE;
+}
+
+
+// adds a morph mask to the appropriate baked texture structure
+void LLAvatarAppearance::addMaskedMorph(EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer)
+{
+ if (index < BAKED_NUM_INDICES)
+ {
+ LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
+ mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+ }
+}
+
+
+//static
+BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )
+{
+ switch( te )
+ {
+ case TEX_UPPER_SHIRT:
+ param_name[0] = 803; //"shirt_red";
+ param_name[1] = 804; //"shirt_green";
+ param_name[2] = 805; //"shirt_blue";
+ break;
+
+ case TEX_LOWER_PANTS:
+ param_name[0] = 806; //"pants_red";
+ param_name[1] = 807; //"pants_green";
+ param_name[2] = 808; //"pants_blue";
+ break;
+
+ case TEX_LOWER_SHOES:
+ param_name[0] = 812; //"shoes_red";
+ param_name[1] = 813; //"shoes_green";
+ param_name[2] = 817; //"shoes_blue";
+ break;
+
+ case TEX_LOWER_SOCKS:
+ param_name[0] = 818; //"socks_red";
+ param_name[1] = 819; //"socks_green";
+ param_name[2] = 820; //"socks_blue";
+ break;
+
+ case TEX_UPPER_JACKET:
+ case TEX_LOWER_JACKET:
+ param_name[0] = 834; //"jacket_red";
+ param_name[1] = 835; //"jacket_green";
+ param_name[2] = 836; //"jacket_blue";
+ break;
+
+ case TEX_UPPER_GLOVES:
+ param_name[0] = 827; //"gloves_red";
+ param_name[1] = 829; //"gloves_green";
+ param_name[2] = 830; //"gloves_blue";
+ break;
+
+ case TEX_UPPER_UNDERSHIRT:
+ param_name[0] = 821; //"undershirt_red";
+ param_name[1] = 822; //"undershirt_green";
+ param_name[2] = 823; //"undershirt_blue";
+ break;
+
+ case TEX_LOWER_UNDERPANTS:
+ param_name[0] = 824; //"underpants_red";
+ param_name[1] = 825; //"underpants_green";
+ param_name[2] = 826; //"underpants_blue";
+ break;
+
+ case TEX_SKIRT:
+ param_name[0] = 921; //"skirt_red";
+ param_name[1] = 922; //"skirt_green";
+ param_name[2] = 923; //"skirt_blue";
+ break;
+
+ case TEX_HEAD_TATTOO:
+ case TEX_LOWER_TATTOO:
+ case TEX_UPPER_TATTOO:
+ param_name[0] = 1071; //"tattoo_red";
+ param_name[1] = 1072; //"tattoo_green";
+ param_name[2] = 1073; //"tattoo_blue";
+ break;
+
+ default:
+ llassert(0);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void LLAvatarAppearance::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
+{
+ U32 param_name[3];
+ if( teToColorParams( te, param_name ) )
+ {
+ setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
+ setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
+ setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
+ }
+}
+
+LLColor4 LLAvatarAppearance::getClothesColor( ETextureIndex te )
+{
+ LLColor4 color;
+ U32 param_name[3];
+ if( teToColorParams( te, param_name ) )
+ {
+ color.mV[VX] = getVisualParamWeight( param_name[0] );
+ color.mV[VY] = getVisualParamWeight( param_name[1] );
+ color.mV[VZ] = getVisualParamWeight( param_name[2] );
+ }
+ return color;
+}
+// static
+LLColor4 LLAvatarAppearance::getDummyColor()
+{
+ return DUMMY_COLOR;
+}
+
+LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) const
+{
+ if (color_name=="skin_color" && mTexSkinColor)
+ {
+ return mTexSkinColor->getColor();
+ }
+ else if(color_name=="hair_color" && mTexHairColor)
+ {
+ return mTexHairColor->getColor();
+ }
+ if(color_name=="eye_color" && mTexEyeColor)
+ {
+ return mTexEyeColor->getColor();
+ }
+ else
+ {
+// return LLColor4( .5f, .5f, .5f, .5f );
+ return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+ }
+}
+
+// Unlike most wearable functions, this works for both self and other.
+// virtual
+BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const
+{
+ return mWearableData->getWearableCount(type) > 0;
+}
+
+LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const
+{
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
+ return mBakedTextureDatas[baked_index].mTexLayerSet;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCollisionVolumes()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
+{
+ deleteAndClearArray(mCollisionVolumes);
+ mNumCollisionVolumes = 0;
+
+ mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
+ if (!mCollisionVolumes)
+ {
+ return FALSE;
+ }
+
+ mNumCollisionVolumes = num;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarBoneInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+{
+ if (node->hasName("bone"))
+ {
+ mIsJoint = TRUE;
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!node->getFastAttributeString(name_string, mName))
+ {
+ llwarns << "Bone without name" << llendl;
+ return FALSE;
+ }
+ }
+ else if (node->hasName("collision_volume"))
+ {
+ mIsJoint = FALSE;
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!node->getFastAttributeString(name_string, mName))
+ {
+ mName = "Collision Volume";
+ }
+ }
+ else
+ {
+ llwarns << "Invalid node " << node->getName() << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+ if (!node->getFastAttributeVector3(pos_string, mPos))
+ {
+ llwarns << "Bone without position" << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+ if (!node->getFastAttributeVector3(rot_string, mRot))
+ {
+ llwarns << "Bone without rotation" << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+ if (!node->getFastAttributeVector3(scale_string, mScale))
+ {
+ llwarns << "Bone without scale" << llendl;
+ return FALSE;
+ }
+
+ if (mIsJoint)
+ {
+ static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+ if (!node->getFastAttributeVector3(pivot_string, mPivot))
+ {
+ llwarns << "Bone without pivot" << llendl;
+ return FALSE;
+ }
+ }
+
+ // parse children
+ LLXmlTreeNode* child;
+ for( child = node->getFirstChild(); child; child = node->getNextChild() )
+ {
+ LLAvatarBoneInfo *child_info = new LLAvatarBoneInfo;
+ if (!child_info->parseXml(child))
+ {
+ delete child_info;
+ return FALSE;
+ }
+ mChildList.push_back(child_info);
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarSkeletonInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+{
+ static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+ if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+ {
+ llwarns << "Couldn't find number of bones." << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+ node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+
+ LLXmlTreeNode* child;
+ for( child = node->getFirstChild(); child; child = node->getNextChild() )
+ {
+ LLAvatarBoneInfo *info = new LLAvatarBoneInfo;
+ if (!info->parseXml(child))
+ {
+ delete info;
+ llwarns << "Error parsing bone in skeleton file" << llendl;
+ return FALSE;
+ }
+ mBoneInfoList.push_back(info);
+ }
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// parseXmlSkeletonNode(): parses nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
+{
+ LLXmlTreeNode* node = root->getChildByName( "skeleton" );
+ if( !node )
+ {
+ llwarns << "avatar file: missing " << llendl;
+ return FALSE;
+ }
+
+ LLXmlTreeNode* child;
+
+ // SKELETON DISTORTIONS
+ for (child = node->getChildByName( "param" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ if (!child->getChildByName("param_skeleton"))
+ {
+ if (child->getChildByName("param_morph"))
+ {
+ llwarns << "Can't specify morph param in skeleton definition." << llendl;
+ }
+ else
+ {
+ llwarns << "Unknown param type." << llendl;
+ }
+ continue;
+ }
+
+ LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
+ if (!info->parseXml(child))
+ {
+ delete info;
+ return FALSE;
+ }
+
+ mSkeletalDistortionInfoList.push_back(info);
+ }
+
+ // ATTACHMENT POINTS
+ for (child = node->getChildByName( "attachment_point" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ LLAvatarAttachmentInfo* info = new LLAvatarAttachmentInfo();
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!child->getFastAttributeString(name_string, info->mName))
+ {
+ llwarns << "No name supplied for attachment point." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
+ if (!child->getFastAttributeString(joint_string, info->mJointName))
+ {
+ llwarns << "No bone declared in attachment point " << info->mName << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
+ if (child->getFastAttributeVector3(position_string, info->mPosition))
+ {
+ info->mHasPosition = TRUE;
+ }
+
+ static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
+ if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
+ {
+ info->mHasRotation = TRUE;
+ }
+ static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
+ if (child->getFastAttributeS32(group_string, info->mGroup))
+ {
+ if (info->mGroup == -1)
+ info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
+ }
+
+ static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
+ if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
+ {
+ llwarns << "No id supplied for attachment point " << info->mName << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
+ child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
+
+ static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
+ child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
+
+ static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
+ child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
+
+ mAttachmentInfoList.push_back(info);
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlMeshNodes(): parses nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+{
+ for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
+ node;
+ node = root->getNextNamedChild())
+ {
+ LLAvatarMeshInfo *info = new LLAvatarMeshInfo;
+
+ // attribute: type
+ static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
+ if( !node->getFastAttributeString( type_string, info->mType ) )
+ {
+ llwarns << "Avatar file: is missing type attribute. Ignoring element. " << llendl;
+ delete info;
+ return FALSE; // Ignore this element
+ }
+
+ static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
+ if (!node->getFastAttributeS32( lod_string, info->mLOD ))
+ {
+ llwarns << "Avatar file: is missing lod attribute. Ignoring element. " << llendl;
+ delete info;
+ return FALSE; // Ignore this element
+ }
+
+ static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+ if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
+ {
+ llwarns << "Avatar file: is missing file_name attribute. Ignoring: " << info->mType << llendl;
+ delete info;
+ return FALSE; // Ignore this element
+ }
+
+ static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
+ node->getFastAttributeString( reference_string, info->mReferenceMeshName );
+
+ // attribute: min_pixel_area
+ static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
+ static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
+ if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
+ {
+ F32 min_pixel_area = 0.1f;
+ if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
+ {
+ // this is square root of pixel area (sensible to use linear space in defining lods)
+ min_pixel_area = min_pixel_area * min_pixel_area;
+ }
+ info->mMinPixelArea = min_pixel_area;
+ }
+
+ // Parse visual params for this node only if we haven't already
+ for (LLXmlTreeNode* child = node->getChildByName( "param" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ if (!child->getChildByName("param_morph"))
+ {
+ if (child->getChildByName("param_skeleton"))
+ {
+ llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
+ }
+ else
+ {
+ llwarns << "Unknown param type." << llendl;
+ }
+ continue;
+ }
+
+ LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
+ if (!morphinfo->parseXml(child))
+ {
+ delete morphinfo;
+ delete info;
+ return -1;
+ }
+ BOOL shared = FALSE;
+ static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
+ child->getFastAttributeBOOL(shared_string, shared);
+
+ info->mPolyMorphTargetInfoList.push_back(LLAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
+ }
+
+ mMeshInfoList.push_back(info);
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlColorNodes(): parses nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+{
+ for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
+ color_node;
+ color_node = root->getNextNamedChild())
+ {
+ std::string global_color_name;
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (color_node->getFastAttributeString( name_string, global_color_name ) )
+ {
+ if( global_color_name == "skin_color" )
+ {
+ if (mTexSkinColorInfo)
+ {
+ llwarns << "avatar file: multiple instances of skin_color" << llendl;
+ return FALSE;
+ }
+ mTexSkinColorInfo = new LLTexGlobalColorInfo;
+ if( !mTexSkinColorInfo->parseXml( color_node ) )
+ {
+ deleteAndClear(mTexSkinColorInfo);
+ llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else if( global_color_name == "hair_color" )
+ {
+ if (mTexHairColorInfo)
+ {
+ llwarns << "avatar file: multiple instances of hair_color" << llendl;
+ return FALSE;
+ }
+ mTexHairColorInfo = new LLTexGlobalColorInfo;
+ if( !mTexHairColorInfo->parseXml( color_node ) )
+ {
+ deleteAndClear(mTexHairColorInfo);
+ llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else if( global_color_name == "eye_color" )
+ {
+ if (mTexEyeColorInfo)
+ {
+ llwarns << "avatar file: multiple instances of eye_color" << llendl;
+ return FALSE;
+ }
+ mTexEyeColorInfo = new LLTexGlobalColorInfo;
+ if( !mTexEyeColorInfo->parseXml( color_node ) )
+ {
+ llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlLayerNodes(): parses nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
+{
+ for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
+ layer_node;
+ layer_node = root->getNextNamedChild())
+ {
+ LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
+ if( layer_info->parseXml( layer_node ) )
+ {
+ mLayerInfoList.push_back(layer_info);
+ }
+ else
+ {
+ delete layer_info;
+ llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+{
+ LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
+ if( driver )
+ {
+ for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
+ grand_child;
+ grand_child = driver->getNextNamedChild())
+ {
+ if( grand_child->getChildByName( "param_driver" ) )
+ {
+ LLDriverParamInfo* driver_info = new LLDriverParamInfo();
+ if( driver_info->parseXml( grand_child ) )
+ {
+ mDriverInfoList.push_back(driver_info);
+ }
+ else
+ {
+ delete driver_info;
+ llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
+{
+ LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
+ if( !masks )
+ {
+ return FALSE;
+ }
+
+ for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
+ grand_child;
+ grand_child = masks->getNextNamedChild())
+ {
+ LLAvatarMorphInfo* info = new LLAvatarMorphInfo();
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
+ if (!grand_child->getFastAttributeString(name_string, info->mName))
+ {
+ llwarns << "No name supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
+ if (!grand_child->getFastAttributeString(region_string, info->mRegion))
+ {
+ llwarns << "No region supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
+ if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
+ {
+ llwarns << "No layer supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ // optional parameter. don't throw a warning if not present.
+ static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
+ grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
+
+ mMorphMaskInfoList.push_back(info);
+ }
+
+ return TRUE;
+}
+
+//virtual
+LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer) :
+ mMorphTarget(morph_target),
+ mInvert(invert),
+ mLayer(layer)
+{
+ LLPolyMorphTarget *target = dynamic_cast(morph_target);
+ if (target)
+ {
+ target->addPendingMorphMask();
+ }
+}
+
+
+
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
new file mode 100644
index 000000000..21a813cc8
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.h
@@ -0,0 +1,452 @@
+/**
+ * @file llavatarappearance.h
+ * @brief Declaration of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_AVATAR_APPEARANCE_H
+#define LL_AVATAR_APPEARANCE_H
+
+#include "llcharacter.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "lldriverparam.h"
+#include "lltexlayer.h"
+#include "llviewervisualparam.h"
+#include "llxmltree.h"
+
+class LLTexLayerSet;
+class LLTexGlobalColor;
+class LLTexGlobalColorInfo;
+class LLWearableData;
+class LLAvatarBoneInfo;
+class LLAvatarSkeletonInfo;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLAvatarAppearance
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLAvatarAppearance : public LLCharacter
+{
+ LOG_CLASS(LLAvatarAppearance);
+
+protected:
+ struct LLAvatarXmlInfo;
+
+/********************************************************************************
+ ** **
+ ** INITIALIZATION
+ **/
+private:
+ // Hide default constructor.
+ LLAvatarAppearance() {}
+
+public:
+ LLAvatarAppearance(LLWearableData* wearable_data);
+ virtual ~LLAvatarAppearance();
+
+ static void initClass(); // initializes static members
+ static void cleanupClass(); // Cleanup data that's only init'd once per class.
+ virtual void initInstance(); // Called after construction to initialize the instance.
+ virtual BOOL loadSkeletonNode();
+ BOOL loadMeshNodes();
+ BOOL loadLayersets();
+
+
+/** Initialization
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** INHERITED
+ **/
+
+ //--------------------------------------------------------------------
+ // LLCharacter interface and related
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ LLJoint* getCharacterJoint(U32 num);
+
+ /*virtual*/ const char* getAnimationPrefix() { return "avatar"; }
+ /*virtual*/ LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
+ /*virtual*/ LLJoint* findCollisionVolume(U32 volume_id);
+ /*virtual*/ S32 getCollisionVolumeID(std::string &name);
+ /*virtual*/ LLPolyMesh* getHeadMesh();
+ /*virtual*/ LLPolyMesh* getUpperBodyMesh();
+ LLPolyMesh* getMesh( LLPolyMeshSharedData *shared_data );
+
+ typedef std::map lod_mesh_map_t;
+ typedef std::map mesh_info_t;
+ static void getMeshInfo(mesh_info_t* mesh_info);
+
+/** Inherited
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** STATE
+ **/
+public:
+ virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
+ virtual BOOL isValid() const;
+ virtual BOOL isUsingServerBakes() const = 0;
+ virtual BOOL isUsingLocalAppearance() const = 0;
+ virtual BOOL isEditingAppearance() const = 0;
+
+ bool isBuilt() const { return mIsBuilt; }
+
+ virtual std::string getFullname() const = 0;
+/** State
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** SKELETON
+ **/
+
+protected:
+ virtual LLAvatarJoint* createAvatarJoint() = 0;
+ virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0;
+ virtual LLAvatarJointMesh* createAvatarJointMesh() = 0;
+public:
+ F32 getPelvisToFoot() const { return mPelvisToFoot; }
+ /*virtual*/ LLJoint* getRootJoint() { return mRoot; }
+
+ LLVector3 mHeadOffset; // current head position
+ LLAvatarJoint *mRoot;
+
+ typedef std::map joint_map_t;
+ joint_map_t mJointMap;
+
+ void computeBodySize();
+
+
+protected:
+ static BOOL parseSkeletonFile(const std::string& filename);
+ virtual void buildCharacter();
+ virtual BOOL loadAvatar();
+ virtual void bodySizeChanged() = 0;
+
+ BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num);
+ BOOL allocateCharacterJoints(U32 num);
+ BOOL buildSkeleton(const LLAvatarSkeletonInfo *info);
+protected:
+ void clearSkeleton();
+ BOOL mIsBuilt; // state of deferred character building
+ typedef std::vector avatar_joint_list_t;
+ avatar_joint_list_t mSkeleton;
+
+ //--------------------------------------------------------------------
+ // Pelvis height adjustment members.
+ //--------------------------------------------------------------------
+public:
+ LLVector3 mBodySize;
+protected:
+ F32 mPelvisToFoot;
+
+ //--------------------------------------------------------------------
+ // Cached pointers to well known joints
+ //--------------------------------------------------------------------
+public:
+ LLJoint* mPelvisp;
+ LLJoint* mTorsop;
+ LLJoint* mChestp;
+ LLJoint* mNeckp;
+ LLJoint* mHeadp;
+ LLJoint* mSkullp;
+ LLJoint* mEyeLeftp;
+ LLJoint* mEyeRightp;
+ LLJoint* mHipLeftp;
+ LLJoint* mHipRightp;
+ LLJoint* mKneeLeftp;
+ LLJoint* mKneeRightp;
+ LLJoint* mAnkleLeftp;
+ LLJoint* mAnkleRightp;
+ LLJoint* mFootLeftp;
+ LLJoint* mFootRightp;
+ LLJoint* mWristLeftp;
+ LLJoint* mWristRightp;
+
+ //--------------------------------------------------------------------
+ // XML parse tree
+ //--------------------------------------------------------------------
+protected:
+ static LLXmlTree sXMLTree; // avatar config file
+ static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
+
+ static LLAvatarSkeletonInfo* sAvatarSkeletonInfo;
+ static LLAvatarXmlInfo* sAvatarXmlInfo;
+
+
+/** Skeleton
+ ** **
+ *******************************************************************************/
+
+
+/********************************************************************************
+ ** **
+ ** RENDERING
+ **/
+public:
+ BOOL mIsDummy; // for special views
+
+ //--------------------------------------------------------------------
+ // Morph masks
+ //--------------------------------------------------------------------
+public:
+ void addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer);
+ virtual void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
+
+/** Rendering
+ ** **
+ *******************************************************************************/
+
+ //--------------------------------------------------------------------
+ // Composites
+ //--------------------------------------------------------------------
+public:
+ virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result) = 0;
+
+/********************************************************************************
+ ** **
+ ** MESHES
+ **/
+
+public:
+ virtual void updateMeshTextures() = 0;
+ virtual void dirtyMesh() = 0; // Dirty the avatar mesh
+protected:
+ virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
+
+protected:
+ typedef std::multimap polymesh_map_t;
+ polymesh_map_t mPolyMeshes;
+ avatar_joint_list_t mMeshLOD;
+
+/** Meshes
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** APPEARANCE
+ **/
+
+ //--------------------------------------------------------------------
+ // Clothing colors (convenience functions to access visual parameters)
+ //--------------------------------------------------------------------
+public:
+ void setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
+ LLColor4 getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te);
+ static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
+
+ //--------------------------------------------------------------------
+ // Global colors
+ //--------------------------------------------------------------------
+public:
+ LLColor4 getGlobalColor(const std::string& color_name ) const;
+ virtual void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake) = 0;
+protected:
+ LLTexGlobalColor* mTexSkinColor;
+ LLTexGlobalColor* mTexHairColor;
+ LLTexGlobalColor* mTexEyeColor;
+
+ //--------------------------------------------------------------------
+ // Visibility
+ //--------------------------------------------------------------------
+public:
+ static LLColor4 getDummyColor();
+/** Appearance
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** WEARABLES
+ **/
+
+public:
+ LLWearableData* getWearableData() { return mWearableData; }
+ const LLWearableData* getWearableData() const { return mWearableData; }
+ virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0;
+ virtual BOOL isWearingWearableType(LLWearableType::EType type ) const;
+
+private:
+ LLWearableData* mWearableData;
+
+/********************************************************************************
+ ** **
+ ** BAKED TEXTURES
+ **/
+public:
+ LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+
+protected:
+ virtual LLTexLayerSet* createTexLayerSet() = 0;
+
+protected:
+ class LLMaskedMorph;
+ typedef std::deque morph_list_t;
+ struct BakedTextureData
+ {
+ LLUUID mLastTextureID;
+ LLTexLayerSet* mTexLayerSet; // Only exists for self
+ bool mIsLoaded;
+ bool mIsUsed;
+ LLAvatarAppearanceDefines::ETextureIndex mTextureIndex;
+ U32 mMaskTexName;
+ // Stores pointers to the joint meshes that this baked texture deals with
+ avatar_joint_mesh_list_t mJointMeshes;
+ morph_list_t mMaskedMorphs;
+ };
+ typedef std::vector bakedtexturedata_vec_t;
+ bakedtexturedata_vec_t mBakedTextureDatas;
+
+/********************************************************************************
+ ** **
+ ** PHYSICS
+ **/
+
+ //--------------------------------------------------------------------
+ // Collision volumes
+ //--------------------------------------------------------------------
+public:
+ S32 mNumCollisionVolumes;
+ LLAvatarJointCollisionVolume* mCollisionVolumes;
+protected:
+ BOOL allocateCollisionVolumes(U32 num);
+
+/** Physics
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** SUPPORT CLASSES
+ **/
+
+ struct LLAvatarXmlInfo
+ {
+ LLAvatarXmlInfo();
+ ~LLAvatarXmlInfo();
+
+ BOOL parseXmlSkeletonNode(LLXmlTreeNode* root);
+ BOOL parseXmlMeshNodes(LLXmlTreeNode* root);
+ BOOL parseXmlColorNodes(LLXmlTreeNode* root);
+ BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
+ BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
+ BOOL parseXmlMorphNodes(LLXmlTreeNode* root);
+
+ struct LLAvatarMeshInfo
+ {
+ typedef std::pair morph_info_pair_t; // LLPolyMorphTargetInfo stored here
+ typedef std::vector morph_info_list_t;
+
+ LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
+ ~LLAvatarMeshInfo()
+ {
+ morph_info_list_t::iterator iter;
+ for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
+ {
+ delete iter->first;
+ }
+ mPolyMorphTargetInfoList.clear();
+ }
+
+ std::string mType;
+ S32 mLOD;
+ std::string mMeshFileName;
+ std::string mReferenceMeshName;
+ F32 mMinPixelArea;
+ morph_info_list_t mPolyMorphTargetInfoList;
+ };
+ typedef std::vector mesh_info_list_t;
+ mesh_info_list_t mMeshInfoList;
+
+ typedef std::vector skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here
+ skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
+
+ struct LLAvatarAttachmentInfo
+ {
+ LLAvatarAttachmentInfo()
+ : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
+ mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
+ std::string mName;
+ std::string mJointName;
+ LLVector3 mPosition;
+ LLVector3 mRotationEuler;
+ S32 mGroup;
+ S32 mAttachmentID;
+ S32 mPieMenuSlice;
+ BOOL mVisibleFirstPerson;
+ BOOL mIsHUDAttachment;
+ BOOL mHasPosition;
+ BOOL mHasRotation;
+ };
+ typedef std::vector attachment_info_list_t;
+ attachment_info_list_t mAttachmentInfoList;
+
+ LLTexGlobalColorInfo *mTexSkinColorInfo;
+ LLTexGlobalColorInfo *mTexHairColorInfo;
+ LLTexGlobalColorInfo *mTexEyeColorInfo;
+
+ typedef std::vector layer_info_list_t;
+ layer_info_list_t mLayerInfoList;
+
+ typedef std::vector driver_info_list_t;
+ driver_info_list_t mDriverInfoList;
+
+ struct LLAvatarMorphInfo
+ {
+ LLAvatarMorphInfo()
+ : mInvert(FALSE) {}
+ std::string mName;
+ std::string mRegion;
+ std::string mLayer;
+ BOOL mInvert;
+ };
+
+ typedef std::vector morph_info_list_t;
+ morph_info_list_t mMorphMaskInfoList;
+ };
+
+
+ class LLMaskedMorph
+ {
+ public:
+ LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer);
+
+ LLVisualParam *mMorphTarget;
+ BOOL mInvert;
+ std::string mLayer;
+ };
+/** Support Classes
+ ** **
+ *******************************************************************************/
+};
+
+#endif // LL_AVATAR_APPEARANCE_H
diff --git a/indra/newview/llvoavatardefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
similarity index 70%
rename from indra/newview/llvoavatardefines.cpp
rename to indra/llappearance/llavatarappearancedefines.cpp
index c0ec8fc61..f1c78946a 100644
--- a/indra/newview/llvoavatardefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -1,51 +1,43 @@
/**
- * @file llvoavatar.cpp
- * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
+ * @file llavatarappearancedefines.cpp
+ * @brief Implementation of LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#include "llviewerprecompiledheaders.h"
-#include "llvoavatardefines.h"
-#include "llviewercontrol.h" // gSavedSettings
+#include "linden_common.h"
+#include "llavatarappearancedefines.h"
-const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512;
-const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512;
-const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512;
+const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
/*********************************************************************************
* Edit this function to add/remove/change textures and mesh definitions for avatars.
- * If these are changed, they MUST be changed in floater_avatar_textures.xml as well!
*/
-LLVOAvatarDictionary::Textures::Textures()
+LLAvatarAppearanceDictionary::Textures::Textures()
{
addEntry(TEX_HEAD_BODYPAINT, new TextureEntry("head_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
addEntry(TEX_UPPER_SHIRT, new TextureEntry("upper_shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", LLWearableType::WT_SHIRT));
@@ -73,15 +65,15 @@ LLVOAvatarDictionary::Textures::Textures()
addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
- addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD));
- addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER));
- addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER));
- addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES));
- addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR));
- addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT));
+ addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head"));
+ addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper"));
+ addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower"));
+ addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes"));
+ addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair"));
+ addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt"));
}
-LLVOAvatarDictionary::BakedTextures::BakedTextures()
+LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
{
// Baked textures
addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED,
@@ -117,36 +109,36 @@ LLVOAvatarDictionary::BakedTextures::BakedTextures()
2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
}
-LLVOAvatarDictionary::Meshes::Meshes()
+LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
{
- // Meshes
- addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4));
- addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, LLViewerJoint::PN_5));
- addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, LLViewerJoint::PN_0)); // no baked mesh associated currently
- addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, LLViewerJoint::PN_1));
- addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, LLViewerJoint::PN_2));
- addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, LLViewerJoint::PN_3));
- addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, LLViewerJoint::PN_3));
- addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5));
+ // MeshEntries
+ addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, PN_4));
+ addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, PN_5));
+ addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, PN_0)); // no baked mesh associated currently
+ addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, PN_1));
+ addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, PN_2));
+ addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, PN_3));
+ addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, PN_3));
+ addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, PN_5));
}
/*
*
*********************************************************************************/
-LLVOAvatarDictionary::LLVOAvatarDictionary()
+LLAvatarAppearanceDictionary::LLAvatarAppearanceDictionary()
{
createAssociations();
}
//virtual
-LLVOAvatarDictionary::~LLVOAvatarDictionary()
+LLAvatarAppearanceDictionary::~LLAvatarAppearanceDictionary()
{
}
// Baked textures are composites of textures; for each such composited texture,
// map it to the baked texture.
-void LLVOAvatarDictionary::createAssociations()
+void LLAvatarAppearanceDictionary::createAssociations()
{
for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
{
@@ -167,11 +159,11 @@ void LLVOAvatarDictionary::createAssociations()
}
-LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
- bool is_local_texture,
- EBakedTextureIndex baked_texture_index,
- const std::string &default_image_name,
- LLWearableType::EType wearable_type) :
+LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name,
+ bool is_local_texture,
+ EBakedTextureIndex baked_texture_index,
+ const std::string &default_image_name,
+ LLWearableType::EType wearable_type) :
LLDictionaryEntry(name),
mIsLocalTexture(is_local_texture),
mIsBakedTexture(!is_local_texture),
@@ -182,17 +174,17 @@ LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
{
}
-LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
+LLAvatarAppearanceDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
const std::string &name,
U8 level,
- LLViewerJoint::PickName pick) :
+ LLJointPickName pick) :
LLDictionaryEntry(name),
mBakedID(baked_index),
mLOD(level),
mPickName(pick)
{
}
-LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
+LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
const std::string &name,
const std::string &hash_name,
U32 num_local_textures,
@@ -223,18 +215,18 @@ LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
}
// static
-ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
+ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
{
- return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
+ return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
}
-//static
-EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
+// static
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
{
U8 index = 0;
while (index < BAKED_NUM_INDICES)
{
- const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
if (be && be->mName.compare(name) == 0)
{
// baked texture found
@@ -246,23 +238,31 @@ EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
return BAKED_NUM_INDICES;
}
-//static
-const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index)
+// static
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
{
- const TextureEntry *texture_dict = getInstance()->getTexture(index);
- const std::string &default_image_name = texture_dict->mDefaultImageName;
- if (default_image_name == "")
+ U8 index = 0;
+ while (index < BAKED_NUM_INDICES)
{
- return IMG_DEFAULT_AVATAR;
- }
- else
- {
- return LLUUID(gSavedSettings.getString(default_image_name));
+ const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ if (be)
+ {
+ const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
+ if (te && te->mDefaultImageName.compare(name) == 0)
+ {
+ // baked texture found
+ return (EBakedTextureIndex) index;
+ }
+ }
+ index++;
}
+ // baked texture could not be found
+ return BAKED_NUM_INDICES;
}
// static
-LLWearableType::EType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index )
+LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
{
return getInstance()->getTexture(index)->mWearableType;
}
+
diff --git a/indra/newview/llvoavatardefines.h b/indra/llappearance/llavatarappearancedefines.h
similarity index 65%
rename from indra/newview/llvoavatardefines.h
rename to indra/llappearance/llavatarappearancedefines.h
index bf157732d..496f85c10 100644
--- a/indra/newview/llvoavatardefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -1,45 +1,40 @@
/**
- * @file llvoavatar.h
- * @brief Declaration of LLVOAvatar class which is a derivation fo
+ * @file llavatarappearancedefines.h
+ * @brief Various LLAvatarAppearance related definitions
* LLViewerObject
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#ifndef LLVOAVATAR_DEFINES_H
-#define LLVOAVATAR_DEFINES_H
+#ifndef LL_AVATARAPPEARANCE_DEFINES_H
+#define LL_AVATARAPPEARANCE_DEFINES_H
#include
-#include "llwearable.h"
-#include "llviewerjoint.h"
+#include "lljointpickname.h"
#include "lldictionary.h"
+#include "llwearabletype.h"
+#include "lluuid.h"
-namespace LLVOAvatarDefines
+namespace LLAvatarAppearanceDefines
{
extern const S32 SCRATCH_TEX_WIDTH;
@@ -47,10 +42,11 @@ extern const S32 SCRATCH_TEX_HEIGHT;
extern const S32 IMPOSTOR_PERIOD;
//--------------------------------------------------------------------
-// texture entry assignment
+// Enums
//--------------------------------------------------------------------
enum ETextureIndex
{
+ TEX_INVALID = -1,
TEX_HEAD_BODYPAINT = 0,
TEX_UPPER_SHIRT,
TEX_LOWER_PANTS,
@@ -59,9 +55,9 @@ enum ETextureIndex
TEX_UPPER_BODYPAINT,
TEX_LOWER_BODYPAINT,
TEX_LOWER_SHOES,
- TEX_HEAD_BAKED, // Pre-composited
- TEX_UPPER_BAKED, // Pre-composited
- TEX_LOWER_BAKED, // Pre-composited
+ TEX_HEAD_BAKED, // Pre-composited
+ TEX_UPPER_BAKED, // Pre-composited
+ TEX_LOWER_BAKED, // Pre-composited
TEX_EYES_BAKED, // Pre-composited
TEX_LOWER_SOCKS,
TEX_UPPER_JACKET,
@@ -70,7 +66,7 @@ enum ETextureIndex
TEX_UPPER_UNDERSHIRT,
TEX_LOWER_UNDERPANTS,
TEX_SKIRT,
- TEX_SKIRT_BAKED, // Pre-composited
+ TEX_SKIRT_BAKED, // Pre-composited
TEX_HAIR_BAKED, // Pre-composited
TEX_LOWER_ALPHA,
TEX_UPPER_ALPHA,
@@ -81,7 +77,7 @@ enum ETextureIndex
TEX_UPPER_TATTOO,
TEX_LOWER_TATTOO,
TEX_NUM_INDICES
-};
+};
enum EBakedTextureIndex
{
@@ -117,21 +113,21 @@ typedef std::vector mesh_vec_t;
typedef std::vector wearables_vec_t;
//------------------------------------------------------------------------
-// LLVOAvatarDictionary
+// LLAvatarAppearanceDictionary
//
// Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e.
// information that is common to all avatars.
//
// This holds const data - it is initialized once and the contents never change after that.
//------------------------------------------------------------------------
-class LLVOAvatarDictionary : public LLSingleton
+class LLAvatarAppearanceDictionary : public LLSingleton
{
//--------------------------------------------------------------------
// Constructors and Destructors
//--------------------------------------------------------------------
public:
- LLVOAvatarDictionary();
- virtual ~LLVOAvatarDictionary();
+ LLAvatarAppearanceDictionary();
+ virtual ~LLAvatarAppearanceDictionary();
private:
void createAssociations();
@@ -141,19 +137,19 @@ private:
public:
struct TextureEntry : public LLDictionaryEntry
{
- TextureEntry(const std::string &name,
- bool is_local_texture,
- EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
- const std::string &default_image_name = "",
+ TextureEntry(const std::string &name, // this must match the xml name used by LLTexLayerInfo::parseXml
+ bool is_local_texture,
+ EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
+ const std::string& default_image_name = "",
LLWearableType::EType wearable_type = LLWearableType::WT_INVALID);
- const std::string mDefaultImageName;
+ const std::string mDefaultImageName;
const LLWearableType::EType mWearableType;
// It's either a local texture xor baked
- BOOL mIsLocalTexture;
- BOOL mIsBakedTexture;
+ BOOL mIsLocalTexture;
+ BOOL mIsBakedTexture;
// If it's a local texture, it may be used by a baked texture
- BOOL mIsUsedByBakedTexture;
- EBakedTextureIndex mBakedTextureIndex;
+ BOOL mIsUsedByBakedTexture;
+ EBakedTextureIndex mBakedTextureIndex;
};
struct Textures : public LLDictionary
@@ -170,22 +166,22 @@ public:
struct MeshEntry : public LLDictionaryEntry
{
MeshEntry(EBakedTextureIndex baked_index,
- const std::string &name,
- U8 level,
- LLViewerJoint::PickName pick);
+ const std::string &name, // names of mesh types as they are used in avatar_lad.xml
+ U8 level,
+ LLJointPickName pick);
// Levels of Detail for each mesh. Must match levels of detail present in avatar_lad.xml
// Otherwise meshes will be unable to be found, or levels of detail will be ignored
- const U8 mLOD;
- const EBakedTextureIndex mBakedID;
- const LLViewerJoint::PickName mPickName;
+ const U8 mLOD;
+ const EBakedTextureIndex mBakedID;
+ const LLJointPickName mPickName;
};
- struct Meshes : public LLDictionary
+ struct MeshEntries : public LLDictionary
{
- Meshes();
- } mMeshes;
- const MeshEntry* getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
- const Meshes& getMeshes() const { return mMeshes; }
+ MeshEntries();
+ } mMeshEntries;
+ const MeshEntry* getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); }
+ const MeshEntries& getMeshEntries() const { return mMeshEntries; }
//--------------------------------------------------------------------
// Baked Textures
@@ -204,7 +200,7 @@ public:
const LLUUID mWearablesHashID;
wearables_vec_t mWearables;
};
-
+
struct BakedTextures: public LLDictionary
{
BakedTextures();
@@ -221,14 +217,13 @@ public:
// find a baked texture index based on its name
static EBakedTextureIndex findBakedByRegionName(std::string name);
-
- static const LLUUID getDefaultTextureImageID(ETextureIndex index);
+ static EBakedTextureIndex findBakedByImageName(std::string name);
// Given a texture entry, determine which wearable type owns it.
static LLWearableType::EType getTEWearableType(ETextureIndex index);
-}; // End LLVOAvatarDictionary
+}; // End LLAvatarAppearanceDictionary
-} // End namespace LLVOAvatarDefines
+} // End namespace LLAvatarAppearanceDefines
-#endif
+#endif //LL_AVATARAPPEARANCE_DEFINES_H
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
new file mode 100644
index 000000000..6ab341af6
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -0,0 +1,326 @@
+/**
+ * @file llavatarjoint.cpp
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llavatarjoint.h"
+
+#include "llgl.h"
+#include "llrender.h"
+#include "llmath.h"
+#include "llglheaders.h"
+#include "llavatarappearance.h"
+
+const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f;
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+BOOL LLAvatarJoint::sDisableLOD = FALSE;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJoint()
+// Class Constructors
+//-----------------------------------------------------------------------------
+LLAvatarJoint::LLAvatarJoint() :
+ LLJoint()
+{
+ init();
+}
+
+LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) :
+ LLJoint(name, parent)
+{
+ init();
+}
+
+LLAvatarJoint::LLAvatarJoint(S32 joint_num) :
+ LLJoint(joint_num)
+{
+ init();
+}
+
+
+void LLAvatarJoint::init()
+{
+ mValid = FALSE;
+ mComponents = SC_JOINT | SC_BONE | SC_AXES;
+ mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD;
+ mPickName = PN_DEFAULT;
+ mVisible = TRUE;
+ mMeshID = 0;
+ mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJoint()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJoint::~LLAvatarJoint()
+{
+}
+
+
+//--------------------------------------------------------------------
+// setValid()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
+{
+ //----------------------------------------------------------------
+ // set visibility for this joint
+ //----------------------------------------------------------------
+ mValid = valid;
+
+ //----------------------------------------------------------------
+ // set visibility for children
+ //----------------------------------------------------------------
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+ joint->setValid(valid, TRUE);
+ }
+ }
+
+}
+
+//--------------------------------------------------------------------
+// setSkeletonComponents()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
+{
+ mComponents = comp;
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast(*iter);
+ joint->setSkeletonComponents(comp, recursive);
+ }
+ }
+}
+
+void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
+{
+ mVisible = visible;
+
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+ joint->setVisible(visible, recursive);
+ }
+ }
+}
+
+void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast(*iter);
+ joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
+ }
+}
+
+void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast(*iter);
+ joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
+ }
+}
+
+void LLAvatarJoint::updateJointGeometry()
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast(*iter);
+ joint->updateJointGeometry();
+ }
+}
+
+
+BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
+{
+ BOOL lod_changed = FALSE;
+ BOOL found_lod = FALSE;
+
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast(*iter);
+ F32 jointLOD = joint->getLOD();
+
+ if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
+ {
+ // we've already found a joint to enable, so enable the rest as alternatives
+ lod_changed |= joint->updateLOD(pixel_area, TRUE);
+ }
+ else
+ {
+ if (pixel_area >= jointLOD || sDisableLOD)
+ {
+ lod_changed |= joint->updateLOD(pixel_area, TRUE);
+ found_lod = TRUE;
+ }
+ else
+ {
+ lod_changed |= joint->updateLOD(pixel_area, FALSE);
+ }
+ }
+ }
+ return lod_changed;
+}
+
+void LLAvatarJoint::dump()
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast(*iter);
+ joint->dump();
+ }
+}
+
+
+void LLAvatarJoint::setMeshesToChildren()
+{
+ removeAllChildren();
+ for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin();
+ iter != mMeshParts.end(); iter++)
+ {
+ addChild((*iter));
+ }
+}
+//-----------------------------------------------------------------------------
+// LLAvatarJointCollisionVolume()
+//-----------------------------------------------------------------------------
+
+LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume()
+{
+ mUpdateXform = FALSE;
+}
+
+/*virtual*/
+U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
+{
+ llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl;
+ return 0;
+}
+
+LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset)
+{
+ mUpdateXform = TRUE;
+
+ LLVector3 result = offset;
+ result.scaleVec(getScale());
+ result.rotVec(getWorldRotation());
+ result += getWorldPosition();
+
+ return result;
+}
+
+void LLAvatarJointCollisionVolume::renderCollision()
+{
+ updateWorldMatrix();
+
+ gGL.pushMatrix();
+ gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
+
+ gGL.diffuseColor3f( 0.f, 0.f, 1.f );
+
+ gGL.begin(LLRender::LINES);
+
+ LLVector3 v[] =
+ {
+ LLVector3(1,0,0),
+ LLVector3(-1,0,0),
+ LLVector3(0,1,0),
+ LLVector3(0,-1,0),
+
+ LLVector3(0,0,-1),
+ LLVector3(0,0,1),
+ };
+
+ //sides
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[2].mV);
+
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[3].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[2].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[3].mV);
+
+
+ //top
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[4].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[4].mV);
+
+ gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[4].mV);
+
+ gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[4].mV);
+
+
+ //bottom
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.end();
+
+ gGL.popMatrix();
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h
new file mode 100644
index 000000000..fec91503c
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.h
@@ -0,0 +1,140 @@
+/**
+ * @file llavatarjoint.h
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARJOINT_H
+#define LL_LLAVATARJOINT_H
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "lljoint.h"
+#include "lljointpickname.h"
+
+class LLFace;
+class LLAvatarJointMesh;
+
+extern const F32 DEFAULT_AVATAR_JOINT_LOD;
+
+//-----------------------------------------------------------------------------
+// class LLViewerJoint
+//-----------------------------------------------------------------------------
+class LLAvatarJoint :
+ public LLJoint
+{
+public:
+ LLAvatarJoint();
+ LLAvatarJoint(S32 joint_num);
+ // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
+ LLAvatarJoint(const std::string &name, LLJoint *parent = NULL);
+ virtual ~LLAvatarJoint();
+
+ // Gets the validity of this joint
+ BOOL getValid() { return mValid; }
+
+ // Sets the validity of this joint
+ virtual void setValid( BOOL valid, BOOL recursive=FALSE );
+
+ // Returns true if this object is transparent.
+ // This is used to determine in which order to draw objects.
+ virtual BOOL isTransparent() { return mIsTransparent; }
+
+ // Returns true if this object should inherit scale modifiers from its immediate parent
+ virtual BOOL inheritScale() { return FALSE; }
+
+ enum Components
+ {
+ SC_BONE = 1,
+ SC_JOINT = 2,
+ SC_AXES = 4
+ };
+
+ // Selects which skeleton components to draw
+ void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
+
+ // Returns which skeleton components are enables for drawing
+ U32 getSkeletonComponents() { return mComponents; }
+
+ // Sets the level of detail for this node as a minimum
+ // pixel area threshold. If the current pixel area for this
+ // object is less than the specified threshold, the node is
+ // not traversed. In addition, if a value is specified (not
+ // default of 0.0), and the pixel area is larger than the
+ // specified minimum, the node is rendered, but no other siblings
+ // of this node under the same parent will be.
+ F32 getLOD() { return mMinPixelArea; }
+ void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
+
+ void setPickName(LLJointPickName name) { mPickName = name; }
+ LLJointPickName getPickName() { return mPickName; }
+
+ void setVisible( BOOL visible, BOOL recursive );
+
+ // Takes meshes in mMeshParts and sets each one as a child joint
+ void setMeshesToChildren();
+
+ // LLViewerJoint interface
+ virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0;
+ virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
+ virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
+ virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
+ virtual void updateJointGeometry();
+ virtual void dump();
+
+
+public:
+ static BOOL sDisableLOD;
+ avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh*
+ void setMeshID( S32 id ) {mMeshID = id;}
+
+protected:
+ void init();
+
+ BOOL mValid;
+ BOOL mIsTransparent;
+ U32 mComponents;
+ F32 mMinPixelArea;
+ LLJointPickName mPickName;
+ BOOL mVisible;
+ S32 mMeshID;
+};
+
+class LLAvatarJointCollisionVolume : public LLAvatarJoint
+{
+public:
+ LLAvatarJointCollisionVolume();
+ virtual ~LLAvatarJointCollisionVolume() {};
+
+ /*virtual*/ BOOL inheritScale() { return TRUE; }
+ /*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
+
+ void renderCollision();
+
+ LLVector3 getVolumePos(LLVector3 &offset);
+};
+
+#endif // LL_LLAVATARJOINT_H
+
+
diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp
new file mode 100644
index 000000000..4a5cff1dc
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.cpp
@@ -0,0 +1,375 @@
+/**
+ * @file LLAvatarJointMesh.cpp
+ * @brief Implementation of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+#include "imageids.h"
+#include "llfasttimer.h"
+#include "llrender.h"
+
+#include "llavatarjointmesh.h"
+#include "llavatarappearance.h"
+//#include "llapr.h"
+//#include "llbox.h"
+//#include "lldrawable.h"
+//#include "lldrawpoolavatar.h"
+//#include "lldrawpoolbump.h"
+//#include "lldynamictexture.h"
+//#include "llface.h"
+//#include "llgldbg.h"
+//#include "llglheaders.h"
+#include "lltexlayer.h"
+//#include "llviewercamera.h"
+//#include "llviewercontrol.h"
+//#include "llviewertexturelist.h"
+//#include "llsky.h"
+//#include "pipeline.h"
+//#include "llviewershadermgr.h"
+#include "llmath.h"
+#include "v4math.h"
+#include "m3math.h"
+#include "m4math.h"
+#include "llmatrix4a.h"
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::LLSkinJoint
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::LLSkinJoint()
+{
+ mJoint = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// ~LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::~LLSkinJoint()
+{
+ mJoint = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint::setupSkinJoint()
+//-----------------------------------------------------------------------------
+BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
+{
+ // find the named joint
+ mJoint = joint;
+ if ( !mJoint )
+ {
+ llinfos << "Can't find joint" << llendl;
+ }
+
+ // compute the inverse root skin matrix
+ mRootToJointSkinOffset.clearVec();
+
+ LLVector3 rootSkinOffset;
+ while (joint)
+ {
+ rootSkinOffset += joint->getSkinOffset();
+ joint = (LLAvatarJoint*)joint->getParent();
+ }
+
+ mRootToJointSkinOffset = -rootSkinOffset;
+ mRootToParentJointSkinOffset = mRootToJointSkinOffset;
+ mRootToParentJointSkinOffset += mJoint->getSkinOffset();
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+BOOL LLAvatarJointMesh::sPipelineRender = FALSE;
+EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
+U32 LLAvatarJointMesh::sClothingMaskImageName = 0;
+LLColor4 LLAvatarJointMesh::sClothingInnerColor;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh()
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::LLAvatarJointMesh()
+ :
+ mTexture( NULL ),
+ mLayerSet( NULL ),
+ mTestImageName( 0 ),
+ mFaceIndexCount(0)
+{
+
+ mColor[0] = 1.0f;
+ mColor[1] = 1.0f;
+ mColor[2] = 1.0f;
+ mColor[3] = 1.0f;
+ mShiny = 0.0f;
+ mCullBackFaces = TRUE;
+
+ mMesh = NULL;
+
+ mNumSkinJoints = 0;
+ mSkinJoints = NULL;
+
+ mFace = NULL;
+
+ mMeshID = 0;
+ mUpdateXform = FALSE;
+
+ mValid = FALSE;
+
+ mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJointMesh()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::~LLAvatarJointMesh()
+{
+ mMesh = NULL;
+ mTexture = NULL;
+ freeSkinData();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::allocateSkinData()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints )
+{
+ mSkinJoints = new LLSkinJoint[ numSkinJoints ];
+ mNumSkinJoints = numSkinJoints;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::freeSkinData()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::freeSkinData()
+{
+ mNumSkinJoints = 0;
+ delete [] mSkinJoints;
+ mSkinJoints = NULL;
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
+{
+ *red = mColor[0];
+ *green = mColor[1];
+ *blue = mColor[2];
+ *alpha = mColor[3];
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
+{
+ mColor[0] = red;
+ mColor[1] = green;
+ mColor[2] = blue;
+ mColor[3] = alpha;
+}
+
+void LLAvatarJointMesh::setColor( const LLColor4& color )
+{
+ mColor = color;
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getTexture()
+//--------------------------------------------------------------------
+//LLViewerTexture *LLAvatarJointMesh::getTexture()
+//{
+// return mTexture;
+//}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setTexture()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setTexture( LLGLTexture *texture )
+{
+ mTexture = texture;
+
+ // texture and dynamic_texture are mutually exclusive
+ if( texture )
+ {
+ mLayerSet = NULL;
+ //texture->bindTexture(0);
+ //texture->setClamp(TRUE, TRUE);
+ }
+}
+
+
+BOOL LLAvatarJointMesh::hasGLTexture() const
+{
+ return mTexture.notNull() && mTexture->hasGLTexture();
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setLayerSet()
+// Sets the shape texture (takes precedence over normal texture)
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set )
+{
+ mLayerSet = layer_set;
+
+ // texture and dynamic_texture are mutually exclusive
+ if( layer_set )
+ {
+ mTexture = NULL;
+ }
+}
+
+BOOL LLAvatarJointMesh::hasComposite() const
+{
+ return (mLayerSet && mLayerSet->hasComposite());
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getMesh()
+//--------------------------------------------------------------------
+LLPolyMesh *LLAvatarJointMesh::getMesh()
+{
+ return mMesh;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::setMesh()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
+{
+ // set the mesh pointer
+ mMesh = mesh;
+
+ // release any existing skin joints
+ freeSkinData();
+
+ if ( mMesh == NULL )
+ {
+ return;
+ }
+
+ // acquire the transform from the mesh object
+ setPosition( mMesh->getPosition() );
+ setRotation( mMesh->getRotation() );
+ setScale( mMesh->getScale() );
+
+ // create skin joints if necessary
+ if ( mMesh->hasWeights() && !mMesh->isLOD())
+ {
+ U32 numJointNames = mMesh->getNumJointNames();
+
+ allocateSkinData( numJointNames );
+ std::string *jointNames = mMesh->getJointNames();
+
+ U32 jn;
+ for (jn = 0; jn < numJointNames; jn++)
+ {
+ //llinfos << "Setting up joint " << jointNames[jn] << llendl;
+ LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) );
+ mSkinJoints[jn].setupSkinJoint( joint );
+ }
+ }
+
+ // setup joint array
+ if (!mMesh->isLOD())
+ {
+ setupJoint((LLAvatarJoint*)getRoot());
+ }
+
+// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
+}
+
+//-----------------------------------------------------------------------------
+// setupJoint()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
+{
+// llinfos << "Mesh: " << getName() << llendl;
+
+// S32 joint_count = 0;
+ U32 sj;
+ for (sj=0; sjmJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix())
+ {
+ // ...then just add ourselves
+ LLAvatarJoint* jointp = js.mJoint;
+ mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
+// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
+// joint_count++;
+ }
+ // otherwise add our parent and ourselves
+ else
+ {
+ mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL));
+// llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
+// joint_count++;
+ mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js));
+// llinfos << "joint " << joint_count << current_joint->getName() << llendl;
+// joint_count++;
+ }
+ }
+
+ // depth-first traversal
+ for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
+ iter != current_joint->mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+ setupJoint(child_joint);
+ }
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
new file mode 100644
index 000000000..17b7b9842
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -0,0 +1,142 @@
+/**
+ * @file llavatarjointmesh.h
+ * @brief Declaration of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARJOINTMESH_H
+#define LL_LLAVATARJOINTMESH_H
+
+#include "llavatarjoint.h"
+#include "llgltexture.h"
+#include "llpolymesh.h"
+#include "v4color.h"
+
+class LLDrawable;
+class LLFace;
+class LLCharacter;
+class LLTexLayerSet;
+
+typedef enum e_avatar_render_pass
+{
+ AVATAR_RENDER_PASS_SINGLE,
+ AVATAR_RENDER_PASS_CLOTHING_INNER,
+ AVATAR_RENDER_PASS_CLOTHING_OUTER
+} EAvatarRenderPass;
+
+class LLSkinJoint
+{
+public:
+ LLSkinJoint();
+ ~LLSkinJoint();
+ BOOL setupSkinJoint( LLAvatarJoint *joint);
+
+ LLAvatarJoint *mJoint;
+ LLVector3 mRootToJointSkinOffset;
+ LLVector3 mRootToParentJointSkinOffset;
+};
+
+//-----------------------------------------------------------------------------
+// class LLViewerJointMesh
+//-----------------------------------------------------------------------------
+class LLAvatarJointMesh : public virtual LLAvatarJoint
+{
+protected:
+ LLColor4 mColor; // color value
+// LLColor4 mSpecular; // specular color (always white for now)
+ F32 mShiny; // shiny value
+ LLPointer mTexture; // ptr to a global texture
+ LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar
+ U32 mTestImageName; // handle to a temporary texture for previewing uploads
+ LLPolyMesh* mMesh; // ptr to a global polymesh
+ BOOL mCullBackFaces; // true by default
+ LLFace* mFace; // ptr to a face w/ AGP copy of mesh
+
+ U32 mFaceIndexCount;
+
+ U32 mNumSkinJoints;
+ LLSkinJoint* mSkinJoints;
+ S32 mMeshID;
+
+public:
+ static BOOL sPipelineRender;
+ //RN: this is here for testing purposes
+ static U32 sClothingMaskImageName;
+ static EAvatarRenderPass sRenderPass;
+ static LLColor4 sClothingInnerColor;
+
+public:
+ // Constructor
+ LLAvatarJointMesh();
+
+ // Destructor
+ virtual ~LLAvatarJointMesh();
+
+ // Gets the shape color
+ void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
+
+ // Sets the shape color
+ void setColor( F32 red, F32 green, F32 blue, F32 alpha );
+ void setColor( const LLColor4& color );
+
+ // Sets the shininess
+ void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
+
+ // Sets the shape texture
+ void setTexture( LLGLTexture *texture );
+
+ BOOL hasGLTexture() const;
+
+ void setTestTexture( U32 name ) { mTestImageName = name; }
+
+ // Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
+ void setLayerSet( LLTexLayerSet* layer_set );
+
+ BOOL hasComposite() const;
+
+ // Gets the poly mesh
+ LLPolyMesh *getMesh();
+
+ // Sets the poly mesh
+ void setMesh( LLPolyMesh *mesh );
+
+ // Sets up joint matrix data for rendering
+ void setupJoint(LLAvatarJoint* current_joint);
+
+ // Sets ID for picking
+ void setMeshID( S32 id ) {mMeshID = id;}
+
+ // Gets ID for picking
+ S32 getMeshID() { return mMeshID; }
+
+ void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
+
+private:
+ // Allocate skin data
+ BOOL allocateSkinData( U32 numSkinJoints );
+
+ // Free skin data
+ void freeSkinData();
+};
+
+#endif // LL_LLAVATARJOINTMESH_H
diff --git a/indra/newview/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp
similarity index 88%
rename from indra/newview/lldriverparam.cpp
rename to indra/llappearance/lldriverparam.cpp
index a1cba861c..8a3181702 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/llappearance/lldriverparam.cpp
@@ -24,22 +24,20 @@
* $/LicenseInfo$
*/
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
#include "lldriverparam.h"
-#include "llfasttimer.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llagent.h"
+#include "llavatarappearance.h"
#include "llwearable.h"
-#include "llagentwearables.h"
+#include "llwearabledata.h"
//-----------------------------------------------------------------------------
// LLDriverParamInfo
//-----------------------------------------------------------------------------
-LLDriverParamInfo::LLDriverParamInfo()
+LLDriverParamInfo::LLDriverParamInfo() :
+ mDriverParam(NULL)
{
}
@@ -112,12 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out)
out << std::endl;
- if(isAgentAvatarValid())
+ if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() &&
+ mDriverParam->getAvatarAppearance()->isValid())
{
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
{
LLDrivenEntryInfo driven = *iter;
- LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
+ LLViewerVisualParam *param =
+ (LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID);
if (param)
{
param->getInfo()->toStream(out);
@@ -139,7 +139,9 @@ void LLDriverParamInfo::toStream(std::ostream &out)
}
else
{
- llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl;
+ llwarns << "could not get parameter " << driven.mDrivenID << " from avatar "
+ << mDriverParam->getAvatarAppearance()
+ << " for driver parameter " << getID() << llendl;
}
out << std::endl;
}
@@ -150,19 +152,16 @@ void LLDriverParamInfo::toStream(std::ostream &out)
// LLDriverParam
//-----------------------------------------------------------------------------
-LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
+LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :
mCurrentDistortionParam( NULL ),
- mAvatarp(avatarp),
- mWearablep(NULL)
-{
- mDefaultVec.clear();
-}
-
-LLDriverParam::LLDriverParam(LLWearable *wearablep) :
- mCurrentDistortionParam( NULL ),
- mAvatarp(NULL),
- mWearablep(wearablep)
+ mAvatarAppearance(appearance),
+ mWearablep(wearable)
{
+ llassert(mAvatarAppearance);
+ if (mWearablep)
+ {
+ llassert(mAvatarAppearance->isSelf());
+ }
mDefaultVec.clear();
}
@@ -177,49 +176,22 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
return FALSE;
mInfo = info;
mID = info->mID;
+ info->mDriverParam = this;
setWeight(getDefaultWeight(), FALSE );
return TRUE;
}
-void LLDriverParam::setWearable(LLWearable *wearablep)
-{
- if (wearablep)
- {
- mWearablep = wearablep;
- mAvatarp = NULL;
- }
-}
-
-void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
-{
- if (avatarp)
- {
- mWearablep = NULL;
- mAvatarp = avatarp;
- }
-}
-
/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
{
- LLDriverParam *new_param;
- if (wearable)
- {
- new_param = new LLDriverParam(wearable);
- }
- else
- {
- if (mWearablep)
- {
- new_param = new LLDriverParam(mWearablep);
- }
- else
- {
- new_param = new LLDriverParam(mAvatarp);
- }
- }
+ llassert(wearable);
+ LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);
+ // FIXME DRANO this clobbers mWearablep, which means any code
+ // currently using mWearablep is wrong, or at least untested.
*new_param = *this;
+ //new_param->mWearablep = wearable;
+// new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables.
return new_param;
}
@@ -456,6 +428,20 @@ const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly
return v;
};
+S32 LLDriverParam::getDrivenParamsCount() const
+{
+ return mDriven.size();
+}
+
+const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const
+{
+ if (0 > index || index >= (S32)mDriven.size())
+ {
+ return NULL;
+ }
+ return mDriven[index].mParam;
+}
+
//-----------------------------------------------------------------------------
// setAnimationTarget()
//-----------------------------------------------------------------------------
@@ -511,6 +497,7 @@ BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross
if (!found)
{
LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
+ if (param) param->setParamLocation(this->getParamLocation());
bool push = param && (!only_cross_params || param->getCrossWearable());
if (push)
{
@@ -555,7 +542,7 @@ void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
// Thus this wearable needs to get updates from the driver wearable.
// The call to setVisualParamWeight seems redundant, but is necessary
// as the number of driven wearables has changed since the last update. -Nyx
- LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
+ LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);
if (wearable)
{
wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
@@ -623,13 +610,22 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
{
- if(isAgentAvatarValid() &&
- mWearablep &&
- driven->mParam->getCrossWearable() &&
- mWearablep->isOnTop())
+ bool use_self = false;
+ if(mWearablep &&
+ mAvatarAppearance->isValid() &&
+ driven->mParam->getCrossWearable())
+ {
+ LLWearable* wearable = dynamic_cast (mWearablep);
+ if (mAvatarAppearance->getWearableData()->isOnTop(wearable))
+ {
+ use_self = true;
+ }
+ }
+
+ if (use_self)
{
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
- gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
+ mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
}
else
{
diff --git a/indra/newview/lldriverparam.h b/indra/llappearance/lldriverparam.h
similarity index 87%
rename from indra/newview/lldriverparam.h
rename to indra/llappearance/lldriverparam.h
index c0976d1d4..1a24cefa1 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/llappearance/lldriverparam.h
@@ -30,8 +30,8 @@
#include "llviewervisualparam.h"
#include "llwearabletype.h"
-class LLPhysicsMotion;
-class LLVOAvatar;
+class LLAvatarAppearance;
+class LLDriverParam;
class LLWearable;
//-----------------------------------------------------------------------------
@@ -71,16 +71,19 @@ public:
protected:
typedef std::deque entry_info_list_t;
entry_info_list_t mDrivenInfoList;
+ LLDriverParam* mDriverParam; // backpointer
};
//-----------------------------------------------------------------------------
class LLDriverParam : public LLViewerVisualParam
{
- friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
+ friend class LLPhysicsMotion;
+private:
+ // Hide the default constructor. Force construction with LLAvatarAppearance.
+ LLDriverParam() {}
public:
- LLDriverParam(LLVOAvatar *avatarp);
- LLDriverParam(LLWearable *wearablep);
+ LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);
~LLDriverParam();
void* operator new(size_t size)
@@ -98,8 +101,9 @@ public:
// This sets mInfo and calls initialization functions
BOOL setInfo(LLDriverParamInfo *info);
- void setWearable(LLWearable *wearablep);
- void setAvatar(LLVOAvatar *avatarp);
+ LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
+ const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+
void updateCrossDrivenParams(LLWearableType::EType driven_type);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
@@ -121,6 +125,9 @@ public:
/*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ S32 getDrivenParamsCount() const;
+ const LLViewerVisualParam* getDrivenParam(S32 index) const;
+
protected:
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
@@ -131,7 +138,7 @@ protected:
entry_list_t mDriven;
LLViewerVisualParam* mCurrentDistortionParam;
// Backlink only; don't make this an LLPointer.
- LLVOAvatar* mAvatarp;
+ LLAvatarAppearance* mAvatarAppearance;
LLWearable* mWearablep;
};
diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h
new file mode 100644
index 000000000..1d41a761f
--- /dev/null
+++ b/indra/llappearance/lljointpickname.h
@@ -0,0 +1,49 @@
+/**
+ * @file lljointpickname.h
+ * @brief Defines OpenGL seleciton stack names
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLJOINTPICKNAME_H
+#define LL_LLJOINTPICKNAME_H
+
+class LLAvatarJointMesh;
+
+// Sets the OpenGL selection stack name that is pushed and popped
+// with this joint state. The default value indicates that no name
+// should be pushed/popped.
+enum LLJointPickName
+{
+ PN_DEFAULT = -1,
+ PN_0 = 0,
+ PN_1 = 1,
+ PN_2 = 2,
+ PN_3 = 3,
+ PN_4 = 4,
+ PN_5 = 5
+};
+
+typedef std::vector avatar_joint_mesh_list_t;
+
+#endif // LL_LLJOINTPICKNAME_H
diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp
similarity index 92%
rename from indra/newview/lllocaltextureobject.cpp
rename to indra/llappearance/lllocaltextureobject.cpp
index 07ec0fab9..7e36a0679 100644
--- a/indra/newview/lllocaltextureobject.cpp
+++ b/indra/llappearance/lllocaltextureobject.cpp
@@ -23,13 +23,14 @@
* $/LicenseInfo$
*/
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
#include "lllocaltextureobject.h"
+#include "llimage.h"
+#include "llrender.h"
#include "lltexlayer.h"
-#include "llviewertexture.h"
-#include "lltextureentry.h"
+#include "llgltexture.h"
#include "lluuid.h"
#include "llwearable.h"
@@ -41,7 +42,7 @@ LLLocalTextureObject::LLLocalTextureObject() :
mImage = NULL;
}
-LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
+LLLocalTextureObject::LLLocalTextureObject(LLGLTexture* image, const LLUUID& id) :
mIsBakedReady(FALSE),
mDiscard(MAX_DISCARD_LEVEL+1)
{
@@ -77,7 +78,7 @@ LLLocalTextureObject::~LLLocalTextureObject()
{
}
-LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
+LLGLTexture* LLLocalTextureObject::getImage() const
{
return mImage;
}
@@ -126,7 +127,7 @@ BOOL LLLocalTextureObject::getBakedReady() const
return mIsBakedReady;
}
-void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
+void LLLocalTextureObject::setImage(LLGLTexture* new_image)
{
mImage = new_image;
}
diff --git a/indra/newview/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h
similarity index 89%
rename from indra/newview/lllocaltextureobject.h
rename to indra/llappearance/lllocaltextureobject.h
index b9bfc5472..9b9f41fd1 100644
--- a/indra/newview/lllocaltextureobject.h
+++ b/indra/llappearance/lllocaltextureobject.h
@@ -29,11 +29,10 @@
#include
-#include "llviewertexture.h"
+#include "llpointer.h"
+#include "llgltexture.h"
-class LLUUID;
class LLTexLayer;
-class LLTextureEntry;
class LLTexLayerTemplate;
class LLWearable;
@@ -44,11 +43,11 @@ class LLLocalTextureObject
{
public:
LLLocalTextureObject();
- LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
+ LLLocalTextureObject(LLGLTexture* image, const LLUUID& id);
LLLocalTextureObject(const LLLocalTextureObject& lto);
~LLLocalTextureObject();
- LLViewerFetchedTexture* getImage() const;
+ LLGLTexture* getImage() const;
LLTexLayer* getTexLayer(U32 index) const;
LLTexLayer* getTexLayer(const std::string &name);
U32 getNumTexLayers() const;
@@ -56,7 +55,7 @@ public:
S32 getDiscard() const;
BOOL getBakedReady() const;
- void setImage(LLViewerFetchedTexture* new_image);
+ void setImage(LLGLTexture* new_image);
BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
@@ -70,7 +69,7 @@ protected:
private:
- LLPointer mImage;
+ LLPointer mImage;
// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
// using shared pointers here only for smart assignment & cleanup
// do NOT create new shared pointers to these objects, or keep pointers to them around
diff --git a/indra/newview/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
similarity index 87%
rename from indra/newview/llpolymesh.cpp
rename to indra/llappearance/llpolymesh.cpp
index 7eae05c10..7ddfc874e 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -27,25 +27,24 @@
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-
+#include "linden_common.h"
+#include "llpolymesh.h"
#include "llfasttimer.h"
#include "llmemory.h"
-#include "llviewercontrol.h"
+//#include "llviewercontrol.h"
#include "llxmltree.h"
-#include "llvoavatar.h"
-#include "llwearable.h"
+#include "llavatarappearance.h"
+//#include "llwearable.h"
#include "lldir.h"
#include "llvolume.h"
#include "llendianswizzle.h"
-#include "llpolymesh.h"
#define HEADER_ASCII "Linden Mesh 1.0"
#define HEADER_BINARY "Linden Binary Mesh 1.0"
-extern LLControlGroup gSavedSettings; // read only
+//extern LLControlGroup gSavedSettings; // read only
LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
const std::string &name);
@@ -1492,7 +1491,7 @@ BOOL LLPolyMesh::setSharedFromCurrent()
std::vector< LLCharacter* >::iterator avatar_it;
for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
{
- LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
+ LLAvatarAppearance* avatarp = (LLAvatarAppearance*)*avatar_it;
LLPolyMesh* mesh = avatarp->getMesh(mSharedData);
if (mesh)
{
@@ -1770,250 +1769,4 @@ F32* LLPolyMesh::getWritableWeights() const
return mSharedData->mWeights;
}
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortionInfo()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
-{
-}
-
-BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
-
- if (NULL == skeletalParam)
- {
- llwarns << "Failed to getChildByName(\"param_skeleton\")"
- << llendl;
- return FALSE;
- }
-
- for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
- {
- if (bone->hasName("bone"))
- {
- std::string name;
- LLVector3 scale;
- LLVector3 pos;
- BOOL haspos = FALSE;
-
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!bone->getFastAttributeString(name_string, name))
- {
- llwarns << "No bone name specified for skeletal param." << llendl;
- continue;
- }
-
- static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
- if (!bone->getFastAttributeVector3(scale_string, scale))
- {
- llwarns << "No scale specified for bone " << name << "." << llendl;
- continue;
- }
-
- // optional offset deformation (translation)
- static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
- if (bone->getFastAttributeVector3(offset_string, pos))
- {
- haspos = TRUE;
- }
- mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
- }
- else
- {
- llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
- continue;
- }
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
-{
- mAvatar = avatarp;
- mDefaultVec.splat(0.001f);
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
-{
-}
-
-BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
- setWeight(getDefaultWeight(), FALSE );
-
- LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
- for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
- {
- LLPolySkeletalBoneInfo *bone_info = &(*iter);
- LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
- if (!joint)
- {
- llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
- continue;
- }
-
- if (mJointScales.find(joint) != mJointScales.end())
- {
- llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
- }
-
- // store it
- mJointScales[joint] = bone_info->mScaleDeformation;
-
- // apply to children that need to inherit it
- for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
- iter != joint->mChildren.end(); ++iter)
- {
- LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
- if (child_joint->inheritScale())
- {
- LLVector3 childDeformation = LLVector3(child_joint->getScale());
- childDeformation.scaleVec(bone_info->mScaleDeformation);
- mJointScales[child_joint] = childDeformation;
- }
- }
-
- if (bone_info->mHasPositionDeformation)
- {
- if (mJointOffsets.find(joint) != mJointOffsets.end())
- {
- llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
- }
- mJointOffsets[joint] = bone_info->mPositionDeformation;
- }
- }
- return TRUE;
-}
-
-/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
-{
- LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
- *new_param = *this;
- return new_param;
-}
-
-//-----------------------------------------------------------------------------
-// apply()
-//-----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
-
-void LLPolySkeletalDistortion::apply( ESex avatar_sex )
-{
- LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
-
- F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
-
- LLJoint* joint;
- joint_vec_map_t::iterator iter;
-
- for (iter = mJointScales.begin();
- iter != mJointScales.end();
- iter++)
- {
- joint = iter->first;
- LLVector3 newScale = joint->getScale();
- LLVector3 scaleDelta = iter->second;
- newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
- joint->setScale(newScale);
- }
-
- for (iter = mJointOffsets.begin();
- iter != mJointOffsets.end();
- iter++)
- {
- joint = iter->first;
- LLVector3 newPosition = joint->getPosition();
- LLVector3 positionDelta = iter->second;
- newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
- joint->setPosition(newPosition);
- }
-
- if (mLastWeight != mCurWeight && !mIsAnimating)
- {
- mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
- }
- mLastWeight = mCurWeight;
-}
-
-
-LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
- const std::string &name)
-{
- LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
- cloned_morph_data->mName = name;
- for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
- {
- cloned_morph_data->mCoords[v] = src_data->mCoords[v];
- cloned_morph_data->mNormals[v] = src_data->mNormals[v];
- cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
- }
- return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
- const LLVector3 &direction,
- const std::string &name)
-{
- LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
- cloned_morph_data->mName = name;
- LLVector4a dir;
- dir.load3(direction.mV);
-
- for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
- {
- cloned_morph_data->mCoords[v] = dir;
- cloned_morph_data->mNormals[v].clear();
- cloned_morph_data->mBinormals[v].clear();
- }
- return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
- F32 scale,
- const std::string &name)
-{
- LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
- cloned_morph_data->mName = name;
-
- LLVector4a sc;
- sc.splat(scale);
-
- LLVector4a nsc;
- nsc.set(scale, -scale, scale, scale);
-
- for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
- {
- if (cloned_morph_data->mCoords[v][1] < 0)
- {
- cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
- cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
- cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
- }
- else
- {
- cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
- cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
- cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
- }
- }
- return cloned_morph_data;
-}
-
// End
diff --git a/indra/newview/llpolymesh.h b/indra/llappearance/llpolymesh.h
similarity index 76%
rename from indra/newview/llpolymesh.h
rename to indra/llappearance/llpolymesh.h
index 184372a95..87f421f33 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/llappearance/llpolymesh.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLPOLYMESH_H
-#define LL_LLPOLYMESH_H
+#ifndef LL_LLPOLYMESHINTERFACE_H
+#define LL_LLPOLYMESHINTERFACE_H
#include
#include
+ AgentAppearanceServiceURL
+
+ Comment
+ Current Session Agent Appearance Service URL
+ Persist
+ 0
+ Type
+ String
+ Value
+
+
AlertedUnsupportedHardware
Comment
@@ -2498,6 +2453,28 @@ This should be as low as possible, but too low may break functionality
Value
2
+ AvatarRotateThresholdSlow
+
+ Comment
+ Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving slowly (degrees)
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 60
+
+ AvatarRotateThresholdFast
+
+ Comment
+ Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving fast (degrees)
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 2
+
AvatarBakedTextureUploadTimeout
Comment
@@ -2670,14 +2647,25 @@ This should be as low as possible, but too low may break functionality
BlockAvatarAppearanceMessages
Comment
- Ignore's appearance messages (for simulating Ruth)
+ Ignores appearance messages (for simulating Ruth)
Persist
1
Type
Boolean
Value
- 0
-
+ 0
+
+ BlockSomeAvatarAppearanceVisualParams
+
+ Comment
+ Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth)
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
BrowserProxyAddress
Comment
@@ -4559,6 +4547,17 @@ This should be as low as possible, but too low may break functionality
Value
+ DebugAvatarAppearanceMessage
+
+ Comment
+ Dump a bunch of XML files when handling appearance messages
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
DebugAvatarRezTime
Comment
@@ -4579,6 +4578,17 @@ This should be as low as possible, but too low may break functionality
Type
Boolean
Value
+ 1
+
+ DebugAvatarCompositeBaked
+
+ Comment
+ Colorize avatar meshes based on baked/composite state.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
0
DebugBeaconLineWidth
@@ -4683,7 +4693,7 @@ This should be as low as possible, but too low may break functionality
DebugShowTime
Comment
- Show depth buffer contents
+ Show time info
Persist
1
Type
@@ -7900,7 +7910,7 @@ This should be as low as possible, but too low may break functionality
WebProfileURL
Comment
- URL for SL Web Profiles
+ URL for Web Profiles
Persist
0
Type
@@ -7908,17 +7918,6 @@ This should be as low as possible, but too low may break functionality
Value
https://my.secondlife.com/[AGENT_NAME]
- WebProfileNonProductionURL
-
- Comment
- URL for SL Web Profiles on Non-Production grids
- Persist
- 0
- Type
- String
- Value
- https://my-demo.secondlife.com/[AGENT_NAME]
-
HighResSnapshot
Comment
@@ -8099,6 +8098,17 @@ This should be as low as possible, but too low may break functionality
Value
1.0
+ InventoryDebugSimulateOpFailureRate
+
+ Comment
+ Rate at which we simulate failures of copy/link requests in some operations
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 0.0
+
InventoryDisplayInbox
Comment
@@ -8885,17 +8895,6 @@ This should be as low as possible, but too low may break functionality
Value
20.0
- MapServerURL
-
- Comment
- World map URL template for locating map tiles
- Persist
- 0
- Type
- String
- Value
- http://map.secondlife.com.s3.amazonaws.com/
-
UseWebMapTiles
Comment
@@ -8929,6 +8928,17 @@ This should be as low as possible, but too low may break functionality
Value
128.0
+ MapServerURL
+
+ Comment
+ World map URL template for locating map tiles
+ Persist
+ 0
+ Type
+ String
+ Value
+ http://map.secondlife.com.s3.amazonaws.com/
+
MapShowAgentCount
Comment
@@ -10985,6 +10995,20 @@ This should be as low as possible, but too low may break functionality
Value
0
+ RenderPerformanceTest
+
+ Comment
+
+ Disable rendering of everything but in-world content for
+ performance testing
+
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
RenderLocalLights
@@ -11411,6 +11435,18 @@ This should be as low as possible, but too low may break functionality
0
+ RenderDepthPrePass
+
+ Comment
+ EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+
RenderDepthOfField
Comment
@@ -12033,6 +12069,28 @@ This should be as low as possible, but too low may break functionality
Value
1
+ DisableAllRenderTypes
+
+ Comment
+ Disables all rendering types.
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
+ DisableAllRenderFeatures
+
+ Comment
+ Disables all rendering features.
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
RenderHUDInSnapshot
Comment
@@ -12534,7 +12592,7 @@ This should be as low as possible, but too low may break functionality
RenderUseVAO
Comment
- Use GL Vertex Array Objects
+ [EXPERIMENTAL] Use GL Vertex Array Objects
Persist
1
Type
@@ -12542,6 +12600,17 @@ This should be as low as possible, but too low may break functionality
Value
0
+ RenderUseTransformFeedback
+
+ Comment
+ [EXPERIMENTAL] Use transform feedback shaders for LoD updates
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
RenderVBOMappingDisable
Comment
@@ -14331,6 +14400,72 @@ This should be as low as possible, but too low may break functionality
Value
0
+ TextureFetchUpdateHighPriority
+
+ Comment
+ Number of high priority textures to update per frame
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 32
+
+ TextureFetchUpdateMaxMediumPriority
+
+ Comment
+ Maximum number of medium priority textures to update per frame
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 256
+
+ TextureFetchUpdateMinMediumPriority
+
+ Comment
+ Minimum number of medium priority textures to update per frame
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 32
+
+ TextureFetchUpdatePriorityThreshold
+
+ Comment
+ Threshold under which textures will be considered too low priority and skipped for update
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 0.0
+
+ TextureFetchUpdateSkipLowPriority
+
+ Comment
+ Flag indicating if we want to skip textures with too low of a priority
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ TextureFetchUpdatePriorities
+
+ Comment
+ Number of priority texture to update per frame
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 32
+
TextureLoadFullRes
Comment
@@ -14774,6 +14909,61 @@ This should be as low as possible, but too low may break functionality
Value
1
+ UseEnvironmentFromRegion
+
+ Comment
+ Choose whether to use the region's environment settings, or override them with the local settings.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ UseDayCycle
+
+ Comment
+ Whether to use use a day cycle or a fixed sky.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ WaterPresetName
+
+ Comment
+ Water preset to use. May be superseded by region settings.
+ Persist
+ 1
+ Type
+ String
+ Value
+ Default
+
+ SkyPresetName
+
+ Comment
+ Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName).
+ Persist
+ 1
+ Type
+ String
+ Value
+ Default
+
+ DayCycleName
+
+ Comment
+ Day cycle to use. May be superseded by region settings.
+ Persist
+ 1
+ Type
+ String
+ Value
+ Default
+
UseExternalBrowser
Comment
@@ -14783,7 +14973,7 @@ This should be as low as possible, but too low may break functionality
Type
Boolean
Value
- 0
+ 1
UseInventoryLinks
@@ -14807,6 +14997,17 @@ This should be as low as possible, but too low may break functionality
Value
1
+ RenderSynchronousOcclusion
+
+ Comment
+ Don't let occlusion queries get more than one frame behind (block until they complete).
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
SkipReflectOcclusionUpdates
Comment
@@ -15741,6 +15942,17 @@ This should be as low as possible, but too low may break functionality
Value
-1
+ ForcePeriodicRenderingTime
+
+ Comment
+ Periodically enable all rendering masks for a single frame.
+ Persist
+ 1
+ Type
+ F32
+ Value
+ -1.0
+
ZoomDirect
Comment
@@ -15939,6 +16151,17 @@ This should be as low as possible, but too low may break functionality
Value
1
+ SimulateFBOFailure
+
+ Comment
+ [DEBUG] Make allocateScreenBuffer return false. Used to test error handling.
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
FloaterUploadRect
Comment
diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp
index 824566c78..2d9b32144 100644
--- a/indra/newview/ascentprefsvan.cpp
+++ b/indra/newview/ascentprefsvan.cpp
@@ -39,6 +39,7 @@
#include "llaudioengine.h" //For gAudiop
#include "llstreamingaudio.h" //For LLStreamingAudioInterface
#include "llcolorswatch.h"
+#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llagent.h"
#include "llfloaterchat.h"
diff --git a/indra/newview/hgfloatertexteditor.cpp b/indra/newview/hgfloatertexteditor.cpp
index 12342b4ba..fdda09ea3 100644
--- a/indra/newview/hgfloatertexteditor.cpp
+++ b/indra/newview/hgfloatertexteditor.cpp
@@ -142,7 +142,7 @@ void HGFloaterTextEditor::imageCallback(BOOL success,
}
else
{
- src_vi->setBoostLevel(LLViewerTexture::BOOST_UI);
+ src_vi->setBoostLevel(LLGLTexture::BOOST_UI);
}
}
diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp
index 222969450..674206e79 100644
--- a/indra/newview/hippogridmanager.cpp
+++ b/indra/newview/hippogridmanager.cpp
@@ -73,7 +73,7 @@ HippoGridInfo::Platform HippoGridInfo::getPlatform()
bool HippoGridInfo::isOpenSimulator() const
{
- return (mPlatform == HippoGridInfo::PLATFORM_OPENSIM);
+ return (mPlatform == HippoGridInfo::PLATFORM_OPENSIM || mPlatform == HippoGridInfo::PLATFORM_AURORA);
}
bool HippoGridInfo::isAurora() const
diff --git a/indra/newview/hippolimits.cpp b/indra/newview/hippolimits.cpp
index c5aa2c7b1..2ee9a7344 100644
--- a/indra/newview/hippolimits.cpp
+++ b/indra/newview/hippolimits.cpp
@@ -52,9 +52,9 @@ void HippoLimits::setAuroraLimits()
{
mMaxAgentGroups = gHippoGridManager->getConnectedGrid()->getMaxAgentGroups();
if (mMaxAgentGroups < 0) mMaxAgentGroups = 50;
- mMaxPrimScale = 256.0f;
+ mMaxPrimScale = 8192.0f;
mMinPrimScale = 0.001f;
- mMaxHeight = 8192.0f;
+ mMaxHeight = 10000.0f;
mMinHoleSize = 0.001f;
mMaxHollow = 99.0f;
}
diff --git a/indra/newview/importtracker.cpp b/indra/newview/importtracker.cpp
index 674ea6143..68a75796a 100644
--- a/indra/newview/importtracker.cpp
+++ b/indra/newview/importtracker.cpp
@@ -646,7 +646,7 @@ void ImportTracker::send_inventory(LLSD& prim)
LLFILE* fp = LLFile::fopen(data->filename, "rb");
if(fp)//HACK LOL LOL LOL
{
- LLWearable* wearable = new LLWearable(LLUUID::null);
+ LLViewerWearable* wearable = new LLWearable(LLUUID::null);
wearable->importFile( fp );
//if (!res)
{
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index efc98dd06..5e765d12f 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -35,6 +35,7 @@
#include "llagentwearables.h"
#include "llagentui.h"
#include "llanimationstates.h"
+#include "llappearancemgr.h"
#include "llcallingcard.h"
#include "llcapabilitylistener.h"
#include "llconsole.h"
@@ -104,7 +105,7 @@
#include "NACLantispam.h" // for NaCl Antispam Registry
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
const BOOL ANIMATE = TRUE;
const U8 AGENT_STATE_TYPING = 0x04;
@@ -771,6 +772,18 @@ void LLAgent::toggleTPosed()
setTPosed(posed);
}
+void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id)
+{
+ llinfos << "called" << llendl;
+
+ if (isAgentAvatarValid() &&
+ !gAgentAvatarp->isUsingServerBakes() &&
+ (mRegionp->getCentralBakeVersion()>0))
+ {
+ LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+ }
+}
+
//-----------------------------------------------------------------------------
// setRegion()
@@ -862,6 +875,19 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
{
LLEnvManagerNew::instance().onRegionCrossing();
}
+
+ // If the newly entered region is using server bakes, and our
+ // current appearance is non-baked, request appearance update from
+ // server.
+ if (mRegionp->capabilitiesReceived())
+ {
+ handleServerBakeRegionTransition(mRegionp->getRegionID());
+ }
+ else
+ {
+ // Need to handle via callback after caps arrive.
+ mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1));
+ }
}
@@ -1701,12 +1727,10 @@ void LLAgent::autoPilot(F32 *delta_yaw)
*delta_yaw = yaw;
// Compute when to start slowing down and when to stop
- F32 stop_distance = mAutoPilotStopDistance;
F32 slow_distance;
if (getFlying())
{
slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
- stop_distance = llmax(2.f, mAutoPilotStopDistance);
}
else
{
@@ -3700,7 +3724,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
return;
}
- if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+ if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
{
// ignore baked textures when in customize mode
return;
@@ -3724,7 +3748,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
if ((S32)texture_index < TEX_NUM_INDICES )
{
- const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearanceDictionary::instance().getTexture((ETextureIndex)texture_index);
if (texture_entry)
{
EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
@@ -4400,13 +4424,19 @@ void LLAgent::requestLeaveGodMode()
//-----------------------------------------------------------------------------
void LLAgent::sendAgentSetAppearance()
{
- if (!isAgentAvatarValid()) return;
+ // FIXME DRANO - problems around new-style appearance in an old-style region.
+ // - does this get called?
+ // - need to change mUseServerBakes->FALSE in that case
+ // - need to call processAvatarAppearance as if server had returned this result?
+ // gAgentAvatarp->mUseServerBakes = FALSE;
- if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
+ if (gAgentQueryManager.mNumPendingQueries > 0)
{
return;
}
+ if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return;
+
LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
//dumpAvatarTEs( "sendAgentSetAppearance()" );
@@ -4446,7 +4476,7 @@ void LLAgent::sendAgentSetAppearance()
for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
{
- const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+ const ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
// if we're not wearing a skirt, we don't need the texture to be baked
if (texture_index == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
@@ -4469,7 +4499,7 @@ void LLAgent::sendAgentSetAppearance()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
BOOL generate_valid_hash = TRUE;
- if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
+ if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLAvatarAppearanceDefines::EBakedTextureIndex)baked_index))
{
generate_valid_hash = FALSE;
LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL;
@@ -4478,7 +4508,7 @@ void LLAgent::sendAgentSetAppearance()
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
if (hash.notNull())
{
- ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
+ ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
msg->nextBlockFast(_PREHASH_WearableData);
msg->addUUIDFast(_PREHASH_CacheID, hash);
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index ddb68ddb1..7a37a05f1 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -42,7 +42,7 @@
#include "llagentdata.h" // gAgentID, gAgentSessionID
#include "llcharacter.h"
#include "llcoordframe.h" // for mFrameAgent
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
#include "llviewerinventory.h"
#include "llinventorymodel.h"
#include "v3dmath.h"
@@ -625,6 +625,7 @@ private:
void handleTeleportFinished();
void handleTeleportFailed();
+ void handleServerBakeRegionTransition(const LLUUID& region_id);
//--------------------------------------------------------------------
// Teleport State
@@ -952,7 +953,7 @@ private:
S32 mNumPendingQueries;
S32 mWearablesCacheQueryID; //mTextureCacheQueryID;
U32 mUpdateSerialNum; //mAgentWearablesUpdateSerialNum
- S32 mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES];
+ S32 mActiveCacheQueries[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
};
extern LLAgentQueryManager gAgentQueryManager;
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index c74719a6e..ed7165e50 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -55,7 +55,7 @@
#include "rlvhandler.h"
// [/RLVa:KB]
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
extern LLMenuBarGL* gMenuBarView;
@@ -609,7 +609,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
abs_target_offset.abs();
LLVector3 target_offset_dir = target_offset_origin;
- F32 object_radius = mFocusObject->getVObjRadius();
BOOL target_outside_object_extents = FALSE;
@@ -704,17 +703,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
- // length projected orthogonal to target offset
- F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
-
- // calculate whether the target point would be "visible" if it were outside the bounding box
- // on the opposite of the splitting plane defined by object_split_axis;
- BOOL exterior_target_visible = FALSE;
- if (camera_offset_dist > object_radius)
- {
- // target is visible from camera, so turn off fov zoom
- exterior_target_visible = TRUE;
- }
F32 camera_offset_clip = camera_offset_object * object_split_axis;
F32 target_offset_clip = target_offset_dir * object_split_axis;
@@ -1108,8 +1096,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
if (!isAgentAvatarValid()) return;
- LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation();
- LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation();
+ LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
+ LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
(root_at * last_at_axis > 0.95f))
@@ -1428,7 +1416,7 @@ void LLAgentCamera::updateCamera()
// llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl;
F32 ui_offset = 0.f;
- if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode )
+ if( LLFloaterCustomize::instanceExists() /*CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode*/ )
{
ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global );
}
@@ -1471,7 +1459,7 @@ void LLAgentCamera::updateCamera()
LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +
LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
LLVector3 diff = mCameraPositionAgent - head_pos;
- diff = diff * ~gAgentAvatarp->mRoot.getWorldRotation();
+ diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
LLJoint* torso_joint = gAgentAvatarp->mTorsop;
LLJoint* chest_joint = gAgentAvatarp->mChestp;
@@ -1495,7 +1483,7 @@ void LLAgentCamera::updateCamera()
gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
- gAgentAvatarp->mRoot.updateWorldMatrixChildren();
+ gAgentAvatarp->mRoot->updateWorldMatrixChildren();
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end(); )
@@ -1555,9 +1543,9 @@ F32 LLAgentCamera::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_glo
{
F32 ui_offset = 0.f;
- if( gFloaterCustomize )
+ if( LLFloaterCustomize::instanceExists() )
{
- const LLRect& rect = gFloaterCustomize->getRect();
+ const LLRect& rect = LLFloaterCustomize::getInstance()->getRect();
// Move the camera so that the avatar isn't covered up by this floater.
F32 fraction_of_fov = 0.5f - (0.5f * (1.f - llmin(1.f, ((F32)rect.getWidth() / (F32)gViewerWindow->getWindowWidth()))));
@@ -1726,7 +1714,6 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor()
else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
{
// don't FOV zoom on mostly transparent objects
- LLVector3 focus_offset = mFocusObjectOffset;
F32 obj_min_dist = 0.f;
if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist"))
calcCameraMinDistance(obj_min_dist);
@@ -1754,7 +1741,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
F32 camera_land_height;
LLVector3d frame_center_global = !isAgentAvatarValid() ?
gAgent.getPositionGlobal() :
- gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+ gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
BOOL isConstrained = FALSE;
LLVector3d head_offset;
@@ -1893,7 +1880,6 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
// set the global camera position
LLVector3d camera_offset;
- LLVector3 av_pos = !isAgentAvatarValid() ? LLVector3::zero : gAgentAvatarp->getRenderPosition();
camera_offset.setVec( local_camera_offset );
camera_position_global = frame_center_global + head_offset + camera_offset;
@@ -2341,7 +2327,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToCustomizeAvatar()
{
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())
{
return;
}
@@ -2380,29 +2366,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
gFocusMgr.setKeyboardFocus( NULL );
gFocusMgr.setMouseCapture( NULL );
- LLVOAvatarSelf::onCustomizeStart();
+ // Remove any pitch or rotation from the avatar
+ LLVector3 at = gAgent.getAtAxis();
+ at.mV[VZ] = 0.f;
+ at.normalize();
+ gAgent.resetAxes(at);
- if (isAgentAvatarValid())
+ gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+ gAgent.setCustomAnim(TRUE);
+ gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+ LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
+
+ if (turn_motion)
{
- // Remove any pitch or rotation from the avatar
- LLVector3 at = gAgent.getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
-
- gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
- gAgent.setCustomAnim(TRUE);
- gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
- LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
-
- if (turn_motion)
- {
- // delay camera animation long enough to play through turn animation
- setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
- }
-
- gAgentAvatarp->invalidateAll();
- gAgentAvatarp->updateMeshTextures();
+ // delay camera animation long enough to play through turn animation
+ setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
}
}
//
@@ -2625,7 +2603,7 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con
{
startCameraAnimation();
- if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode )
+ if( LLFloaterCustomize::instanceExists()/*CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode*/ )
{
// Compensate for the fact that the camera has already been offset to make room for LLFloaterCustomize.
mAnimationCameraStartGlobal -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal ));
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index ab33da86c..44aac869e 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -69,24 +69,21 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
bool LLAgentWearables::mInitialWearablesLoaded = false;
// [/SL:KB]
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
///////////////////////////////////////////////////////////////////////////////
// Callback to wear and start editing an item that has just been created.
-class LLWearAndEditCallback : public LLInventoryCallback
+void wear_and_edit_cb(const LLUUID& inv_item)
{
- void fire(const LLUUID& inv_item)
- {
- if (inv_item.isNull()) return;
-
- // Request editing the item after it gets worn.
- gAgentWearables.requestEditingWearable(inv_item);
-
- // Wear it.
- LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
- }
-};
+ if (inv_item.isNull()) return;
+
+ // Request editing the item after it gets worn.
+ gAgentWearables.requestEditingWearable(inv_item);
+
+ // Wear it.
+ LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
+}
///////////////////////////////////////////////////////////////////////////////
@@ -95,7 +92,7 @@ class LLWearAndEditCallback : public LLInventoryCallback
// wearable type stored in asset is some other value.
// Calling this function whenever a wearable is added to increase visibility if this problem
// turns up in other inventories.
-void checkWearableAgainstInventory(LLWearable *wearable)
+void checkWearableAgainstInventory(LLViewerWearable *wearable)
{
if (wearable->getItemID().isNull())
return;
@@ -132,7 +129,7 @@ void LLAgentWearables::dump()
llinfos << "Type: " << i << " count " << count << llendl;
for (U32 j=0; joutputRezTiming("Sending wearables request");
sendAgentWearablesRequest();
+ setAvatarAppearance(avatar);
}
}
@@ -226,7 +226,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
* @param todo Bitmask of actions to take on completion.
*/
LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
- LLPointer cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
+ LLPointer cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo) :
mType(type),
mIndex(index),
mWearable(wearable),
@@ -279,7 +279,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index,
const LLUUID& item_id,
- LLWearable* wearable)
+ LLViewerWearable* wearable)
{
llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl;
@@ -326,7 +326,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
{
for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index);
if (wearable)
{
if (wearable->getItemID().isNull())
@@ -368,7 +368,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
U8 type_u8 = (U8)type;
gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 );
- LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0);
if( wearable )
{
//llinfos << "Sending wearable " << wearable->getName() << llendl;
@@ -397,14 +397,14 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
const std::string new_name)
{
//llassert_always(index == 0);
- LLWearable* old_wearable = getWearable(type, index);
+ LLViewerWearable* old_wearable = getViewerWearable(type, index);
if(!old_wearable) return;
bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());
if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion())
{
LLUUID old_item_id = old_wearable->getItemID();
- LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
- new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()?
+ LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()?
setWearable(type,index,new_wearable);
// old_wearable may still be referred to by other inventory items. Revert
@@ -470,7 +470,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
}
}
-LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
+LLViewerWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
const U32 index,
const std::string& new_name,
BOOL save_in_lost_and_found)
@@ -480,7 +480,7 @@ LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
return NULL;
}
- LLWearable* old_wearable = getWearable(type, index);
+ LLViewerWearable* old_wearable = getViewerWearable(type, index);
if (!old_wearable)
{
llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
@@ -495,7 +495,7 @@ LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
}
std::string trunc_name(new_name);
LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
- LLWearable* new_wearable = LLWearableList::instance().createCopy(
+ LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(
old_wearable,
trunc_name);
LLPointer cb =
@@ -534,7 +534,7 @@ LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
{
- LLWearable* wearable = getWearable(type, index);
+ LLViewerWearable* wearable = getViewerWearable(type, index);
llassert(wearable);
if (wearable)
{
@@ -551,7 +551,7 @@ void LLAgentWearables::saveAllWearables()
// return;
//}
- for( S32 i=0; i < LLWearableType::WT_COUNT; i++ )
+ for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
saveWearable((LLWearableType::EType)i, j, FALSE);
@@ -559,23 +559,23 @@ void LLAgentWearables::saveAllWearables()
sendAgentWearablesUpdate();
}
-// Called when the user changes the name of a wearable inventory item that is currenlty being worn.
-void LLAgentWearables::setWearableName( const LLUUID& item_id, const std::string& new_name )
+// Called when the user changes the name of a wearable inventory item that is currently being worn.
+void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& new_name)
{
- for( S32 i=0; i < LLWearableType::WT_COUNT; i++ )
+ for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);
if (curr_item_id == item_id)
{
- LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j);
+ LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j);
llassert(old_wearable);
if (!old_wearable) continue;
std::string old_name = old_wearable->getName();
old_wearable->setName(new_name);
- LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
new_wearable->setItemID(item_id);
LLInventoryItem* item = gInventory.getItem(item_id);
if (item)
@@ -659,14 +659,14 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp
return item;
}
-const LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) const
+const LLViewerWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) const
{
const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
- const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
{
return curr_wearable;
@@ -676,14 +676,14 @@ const LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id
return NULL;
}
-LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id )
+LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
{
const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
- LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
{
return curr_wearable;
@@ -693,13 +693,13 @@ LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id )
return NULL;
}
-LLWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id)
+LLViewerWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id)
{
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
- LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
if (curr_wearable && (curr_wearable->getAssetID() == asset_id))
{
return curr_wearable;
@@ -718,240 +718,63 @@ void LLAgentWearables::sendAgentWearablesRequest()
gAgent.sendReliableMessage();
}
-// Used to enable/disable menu items.
+LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/)
+{
+ return dynamic_cast (getWearable(type, index));
+}
+
+const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const
+{
+ return dynamic_cast (getWearable(type, index));
+}
+
// static
BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
{
return (gAgentWearables.getWearableCount(type) > 0);
}
-LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index)
+// virtual
+void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
{
- //llassert_always(index == 0);
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
+ if (isAgentAvatarValid())
{
- return NULL;
- }
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (index>=wearable_vec.size())
- {
- return NULL;
- }
- else
- {
- return wearable_vec[index];
- }
-}
-
-void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
-{
- //llassert_always(index == 0);
- LLWearable *old_wearable = getWearable(type,index);
- if (!old_wearable)
- {
- pushWearable(type,wearable);
- return;
+ const BOOL upload_result = removed;
+ gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);
}
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- llwarns << "invalid type, type " << type << " index " << index << llendl;
- return;
- }
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (index>=wearable_vec.size())
- {
- llwarns << "invalid index, type " << type << " index " << index << llendl;
- }
- else
- {
- wearable_vec[index] = wearable;
- old_wearable->setLabelUpdated();
- wearableUpdated(wearable);
- checkWearableAgainstInventory(wearable);
- }
-}
+ LLWearableData::wearableUpdated(wearable, removed);
-U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable)
-{
- if (wearable == NULL)
+ if (!removed)
{
- // no null wearables please!
- llwarns << "Null wearable sent for type " << type << llendl;
- return MAX_CLOTHING_PER_TYPE;
- }
-// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
-// {
-// mWearableDatas[type].push_back(wearable);
-// wearableUpdated(wearable);
-// checkWearableAgainstInventory(wearable);
-// return mWearableDatas[type].size()-1;
-// }
-// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
- if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) )
- {
- // Don't add the same wearable twice
- U32 idxWearable = getWearableIndex(wearable);
- RLV_ASSERT(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere*
- if (MAX_CLOTHING_PER_TYPE == idxWearable)
+ LLViewerWearable* viewer_wearable = dynamic_cast(wearable);
+ viewer_wearable->refreshName();
+
+ // Hack pt 2. If the wearable we just loaded has definition version 24,
+ // then force a re-save of this wearable after slamming the version number to 22.
+ // This number was incorrectly incremented for internal builds before release, and
+ // this fix will ensure that the affected wearables are re-saved with the right version number.
+ // the versions themselves are compatible. This code can be removed before release.
+ if( wearable->getDefinitionVersion() == 24 )
{
- mWearableDatas[type].push_back(wearable);
- idxWearable = mWearableDatas[type].size() - 1;
+ wearable->setDefinitionVersion(22);
+ U32 index = getWearableIndex(wearable);
+ llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl;
+ saveWearable(wearable->getType(),index,TRUE);
}
- wearableUpdated(wearable);
- checkWearableAgainstInventory(wearable);
- return idxWearable;
-// [/RLVa:KB]
+
+ //Needed as wearable 'save' process is a mess and fires superfluous updateScrollingPanelList calls
+ //while the wearable being created has not yet been stuffed into the wearable list.
+ //This results in the param hints being buggered and screwing up the current wearable during LLVisualParamHint::preRender,
+ //thus making the wearable 'dirty'. The code below basically 'forces' a refresh of the panel to fix this.
+ if( LLFloaterCustomize::instanceExists() )
+ LLFloaterCustomize::getInstance()->wearablesChanged(wearable->getType());
+
+ checkWearableAgainstInventory(viewer_wearable);
}
- return MAX_CLOTHING_PER_TYPE;
-}
-
-void LLAgentWearables::wearableUpdated(LLWearable *wearable)
-{
- gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);
- wearable->refreshName();
- wearable->setLabelUpdated();
-
- wearable->pullCrossWearableValues();
-
- // Hack pt 2. If the wearable we just loaded has definition version 24,
- // then force a re-save of this wearable after slamming the version number to 22.
- // This number was incorrectly incremented for internal builds before release, and
- // this fix will ensure that the affected wearables are re-saved with the right version number.
- // the versions themselves are compatible. This code can be removed before release.
- if( wearable->getDefinitionVersion() == 24 )
- {
- wearable->setDefinitionVersion(22);
- U32 index = getWearableIndex(wearable);
- llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
- saveWearable(wearable->getType(),index,TRUE);
- }
-
- //Needed as wearable 'save' process is a mess and fires superfluous updateScrollingPanelList calls
- //while the wearable being created has not yet been stuffed into the wearable list.
- //This results in the param hints being buggered and screwing up the current wearable during LLVisualParamHint::preRender,
- //thus making the wearable 'dirty'. The code below basically 'forces' a refresh of the panel to fix this.
- if(gFloaterCustomize)
- gFloaterCustomize->wearablesChanged(wearable->getType());
}
-void LLAgentWearables::popWearable(LLWearable *wearable)
-{
- if (wearable == NULL)
- {
- // nothing to do here. move along.
- return;
- }
-
- U32 index = getWearableIndex(wearable);
- LLWearableType::EType type = wearable->getType();
-
- if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
- {
- popWearable(type, index);
- }
-}
-
-void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)
-{
- //llassert_always(index == 0);
- LLWearable *wearable = getWearable(type, index);
- if (wearable)
- {
- mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE);
- }
- wearable->setLabelUpdated();
- }
-}
-
-U32 LLAgentWearables::getWearableIndex(const LLWearable *wearable) const
-{
- if (wearable == NULL)
- {
- return MAX_CLOTHING_PER_TYPE;
- }
-
- const LLWearableType::EType type = wearable->getType();
- wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- llwarns << "tried to get wearable index with an invalid type!" << llendl;
- return MAX_CLOTHING_PER_TYPE;
- }
- const wearableentry_vec_t& wearable_vec = wearable_iter->second;
- for(U32 index = 0; index < wearable_vec.size(); index++)
- {
- if (wearable_vec[index] == wearable)
- {
- return index;
- }
- }
-
- return MAX_CLOTHING_PER_TYPE;
-}
-
-const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const
-{
- //llassert_always(index == 0);
- wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- return NULL;
- }
- const wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (index>=wearable_vec.size())
- {
- return NULL;
- }
- else
- {
- return wearable_vec[index];
- }
-}
-
-LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
-{
- U32 count = getWearableCount(type);
- if ( count == 0)
- {
- return NULL;
- }
-
- return getWearable(type, count-1);
-}
-
-LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type)
-{
- if (getWearableCount(type) == 0)
- {
- return NULL;
- }
-
- return getWearable(type, 0);
-}
-
-U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
-{
- wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- return 0;
- }
- const wearableentry_vec_t& wearable_vec = wearable_iter->second;
- return wearable_vec.size();
-}
-
-U32 LLAgentWearables::getWearableCount(const U32 tex_index) const
-{
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
- return getWearableCount(wearable_type);
-}
BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
@@ -966,7 +789,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const
const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
{
- const LLWearable *wearable = getWearable(type,index);
+ const LLViewerWearable *wearable = getViewerWearable(type,index);
if (wearable)
return wearable->getItemID();
else
@@ -991,7 +814,9 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_
for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(), endWearable = itWearableType->second.end();
itWearable != endWearable; ++itWearable)
{
- idItems.push_back((*itWearable)->getItemID());
+ LLViewerWearable* wearable = dynamic_cast(*itWearable);
+ if(wearable)
+ idItems.push_back(wearable->getItemID());
}
}
}
@@ -999,7 +824,7 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_
const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
{
- const LLWearable *wearable = getWearable(type,index);
+ const LLViewerWearable *wearable = getViewerWearable(type,index);
if (wearable)
return wearable->getAssetID();
else
@@ -1080,7 +905,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i );
if( asset_id.isNull() )
{
- LLWearable::removeFromAvatar( type, FALSE );
+ LLViewerWearable::removeFromAvatar( type, FALSE );
}
else
{
@@ -1127,7 +952,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
// Try to recover by replacing missing wearable with a new one.
LLNotificationsUtil::add("ReplacedMissingWearable");
lldebugs << "Wearable " << LLWearableType::getTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
- LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
+ LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
setWearable(type,index,new_wearable);
//new_wearable->writeToAvatar( TRUE );
@@ -1162,9 +987,9 @@ void LLAgentWearables::recoverMissingWearableDone()
}
}
-void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
+void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index);
if (!wearable)
{
llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
@@ -1197,7 +1022,7 @@ public:
mItemsToLink,
link_waiter);
}
- void addPendingWearable(LLWearable *wearable)
+ void addPendingWearable(LLViewerWearable *wearable)
{
if (!wearable)
{
@@ -1232,7 +1057,7 @@ public:
LLWearableType::EType type = item->getWearableType();
if (type < LLWearableType::WT_COUNT)
{
- LLWearable *wearable = mWearablesAwaitingItems[type];
+ LLViewerWearable *wearable = mWearablesAwaitingItems[type];
if (wearable)
wearable->setItemID(inv_item);
}
@@ -1245,7 +1070,7 @@ public:
private:
LLInventoryModel::item_array_t mItemsToLink;
- std::vector mWearablesAwaitingItems;
+ std::vector mWearablesAwaitingItems;
};
void LLAgentWearables::createStandardWearables()
@@ -1258,20 +1083,20 @@ void LLAgentWearables::createStandardWearables()
{
TRUE, //LLWearableType::WT_SHAPE
TRUE, //LLWearableType::WT_SKIN
- TRUE, //WT_HAIR
- TRUE, //WT_EYES
- TRUE, //WT_SHIRT
- TRUE, //WT_PANTS
- TRUE, //WT_SHOES
- TRUE, //WT_SOCKS
- FALSE, //WT_JACKET
- FALSE, //WT_GLOVES
- TRUE, //WT_UNDERSHIRT
- TRUE, //WT_UNDERPANTS
- FALSE, //WT_SKIRT
- FALSE, //WT_ALPHA
- FALSE, //WT_TATTOO
- FALSE, //WT_PHYSICS
+ TRUE, //LLWearableType::WT_HAIR
+ TRUE, //LLWearableType::WT_EYES
+ TRUE, //LLWearableType::WT_SHIRT
+ TRUE, //LLWearableType::WT_PANTS
+ TRUE, //LLWearableType::WT_SHOES
+ TRUE, //LLWearableType::WT_SOCKS
+ FALSE, //LLWearableType::WT_JACKET
+ FALSE, //LLWearableType::WT_GLOVES
+ TRUE, //LLWearableType::WT_UNDERSHIRT
+ TRUE, //LLWearableType::WT_UNDERPANTS
+ FALSE, //LLWearableType::WT_SKIRT
+ FALSE, //LLWearableType::WT_ALPHA
+ FALSE, //LLWearableType::WT_TATTOO
+ FALSE //LLWearableType::WT_PHYSICS
};
LLPointer cb = new OnWearableItemCreatedCB;
@@ -1280,7 +1105,7 @@ void LLAgentWearables::createStandardWearables()
if (create[i])
{
llassert(getWearableCount((LLWearableType::EType)i) == 0);
- LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i);
+ LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp);
((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
// no need to update here...
LLUUID category_id = LLUUID::null;
@@ -1339,7 +1164,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
void LLAgentWearables::addWearableToAgentInventory(LLPointer cb,
- LLWearable* wearable,
+ LLViewerWearable* wearable,
const LLUUID& category_id,
BOOL notify)
{
@@ -1377,7 +1202,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_
}
else
{
- LLWearable* old_wearable = getWearable(type,index);
+ LLViewerWearable* old_wearable = getViewerWearable(type,index);
// if (old_wearable)
// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0c) | Modified: RLVa-1.2.0g
@@ -1436,10 +1261,10 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
//llassert_always(index == 0);
if (do_remove_all)
{
- S32 max_entry = mWearableDatas[type].size()-1;
+ S32 max_entry = getWearableCount(type)-1;
for (S32 i=max_entry; i>=0; i--)
{
- LLWearable* old_wearable = getWearable(type,i);
+ LLViewerWearable* old_wearable = getViewerWearable(type,i);
//queryWearableCache(); // moved below
// if (old_wearable)
// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
@@ -1458,7 +1283,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
}
else
{
- LLWearable* old_wearable = getWearable(type, index);
+ LLViewerWearable* old_wearable = getViewerWearable(type, index);
//queryWearableCache(); // moved below
// if (old_wearable)
@@ -1504,7 +1329,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
// Assumes existing wearables are not dirty.
void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
- const LLDynamicArray< LLWearable* >& wearables,
+ const LLDynamicArray< LLViewerWearable* >& wearables,
BOOL remove)
{
llinfos << "setWearableOutfit() start" << llendl;
@@ -1535,7 +1360,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
S32 i;
for (i = 0; i < count; i++)
{
- LLWearable* new_wearable = wearables[i];
+ LLViewerWearable* new_wearable = wearables[i];
LLPointer new_item = items[i];
llassert(new_wearable);
@@ -1601,8 +1426,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
idxCurPerType[type]++;
// [/RLVa:KB]
- wearableUpdated(new_wearable);
- checkWearableAgainstInventory(new_wearable);
+ const BOOL removed = FALSE;
+ wearableUpdated(new_wearable, removed);
}
}
@@ -1645,7 +1470,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// User has picked "wear on avatar" from a menu.
-void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
{
//LLAgentDumper dumper("setWearableItem");
if (isWearingItem(new_item->getUUID()))
@@ -1670,7 +1495,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
{
// Remove old wearable, if any
// MULTI_WEARABLE: hardwired to 0
- LLWearable* old_wearable = getWearable(type,0);
+ LLViewerWearable* old_wearable = getViewerWearable(type,0);
if( old_wearable )
{
const LLUUID& old_item_id = old_wearable->getItemID();
@@ -1696,7 +1521,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
}
// static
-bool LLAgentWearables::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable )
+bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID());
@@ -1732,7 +1557,7 @@ bool LLAgentWearables::onSetWearableDialog( const LLSD& notification, const LLSD
// Called from setWearableItem() and onSetWearableDialog() to actually set the wearable.
// MULTI_WEARABLE: unify code after null objects are gone.
-void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
{
const LLWearableType::EType type = new_wearable->getType();
@@ -1750,7 +1575,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
// Replace the old wearable with a new one.
llassert(new_item->getAssetUUID() == new_wearable->getAssetID());
- LLWearable *old_wearable = getWearable(type,0);
+ LLViewerWearable *old_wearable = getViewerWearable(type,0);
LLUUID old_item_id;
if (old_wearable)
{
@@ -1765,7 +1590,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
gInventory.notifyObservers();
}
llinfos << "Replaced current element 0 for type " << type
- << " size is now " << mWearableDatas[type].size() << llendl;
+ << " size is now " << getWearableCount(type) << llendl;
}
//llinfos << "LLVOAvatar::setWearableItem()" << llendl;
@@ -1777,7 +1602,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
void LLAgentWearables::queryWearableCache()
{
- if (!areWearablesLoaded())
+ if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()))
{
return;
}
@@ -1806,7 +1631,7 @@ void LLAgentWearables::queryWearableCache()
num_queries++;
// *NOTE: make sure at least one request gets packed
- ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+ ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
@@ -1831,46 +1656,14 @@ void LLAgentWearables::queryWearableCache()
}
}
-LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
- BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+// virtual
+void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
{
- LLUUID hash_id;
- bool hash_computed = false;
- LLMD5 hash;
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
-
- for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+ // Add some garbage into the hash so that it becomes invalid.
+ if (isAgentAvatarValid())
{
- const LLWearableType::EType baked_type = baked_dict->mWearables[i];
- const U32 num_wearables = getWearableCount(baked_type);
- for (U32 index = 0; index < num_wearables; ++index)
- {
- const LLWearable* wearable = getWearable(baked_type,index);
- if (wearable)
- {
- LLUUID asset_id = wearable->getAssetID();
- hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
- hash_computed = true;
- }
- }
+ hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
}
- if (hash_computed)
- {
- hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
-
- // Add some garbage into the hash so that it becomes invalid.
- if (!generate_valid_hash)
- {
- if (isAgentAvatarValid())
- {
- hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
- }
- }
- hash.finalize();
- hash.raw_digest(hash_id.mData);
- }
-
- return hash_id;
}
// User has picked "remove from avatar" from a menu.
@@ -2027,31 +1820,6 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
gMessageSystem->sendReliable(gAgent.getRegionHost());
}
-void LLAgentWearables::userRemoveAllAttachments()
-{
- if (!isAgentAvatarValid()) return;
-
- llvo_vec_t objects_to_remove;
-
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end();)
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *attached_object = (*attachment_iter);
- if (attached_object)
- {
- objects_to_remove.push_back(attached_object);
- }
- }
- }
- userRemoveMultipleAttachments(objects_to_remove);
-}
-
void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
{
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
@@ -2146,7 +1914,7 @@ void LLAgentWearables::checkWearablesLoaded() const
// Returns false if the given wearable is already topmost/bottommost
// (depending on closer_to_body parameter).
-bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body)
+bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const
{
const LLWearable* wearable = getWearableFromItemID(item_id);
if (!wearable) return false;
@@ -2174,7 +1942,7 @@ void LLAgentWearables::updateWearablesLoaded()
}
}
-bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
+bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const
{
if (!wearable) return false;
@@ -2189,7 +1957,7 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
{
for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count)
{
- LLWearable *wearable = getWearable((LLWearableType::EType)type,count);
+ LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count);
llassert(wearable);
if (wearable)
{
@@ -2204,32 +1972,43 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos
if (!item) return false;
if (!item->isWearableType()) return false;
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType());
- if (wearable_iter == mWearableDatas.end()) return false;
-
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (wearable_vec.empty()) return false;
+ LLWearableType::EType type = item->getWearableType();
+ U32 wearable_count = getWearableCount(type);
+ if (0 == wearable_count) return false;
const LLUUID& asset_id = item->getAssetUUID();
//nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body)
- if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false;
- if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false;
-
- for (U32 i = 0; i < wearable_vec.size(); ++i)
+ if (closer_to_body)
{
- LLWearable* wearable = wearable_vec[i];
+ LLViewerWearable* bottom_wearable = dynamic_cast( getBottomWearable(type) );
+ if (bottom_wearable->getAssetID() == asset_id)
+ {
+ return false;
+ }
+ }
+ else // !closer_to_body
+ {
+ LLViewerWearable* top_wearable = dynamic_cast( getTopWearable(type) );
+ if (top_wearable->getAssetID() == asset_id)
+ {
+ return false;
+ }
+ }
+
+ for (U32 i = 0; i < wearable_count; ++i)
+ {
+ LLViewerWearable* wearable = getViewerWearable(type, i);
if (!wearable) continue;
if (wearable->getAssetID() != asset_id) continue;
//swapping wearables
U32 swap_i = closer_to_body ? i-1 : i+1;
- wearable_vec[i] = wearable_vec[swap_i];
- wearable_vec[swap_i] = wearable;
+ swapWearables(type, i, swap_i);
- if(gFloaterCustomize)
+ if( LLFloaterCustomize::instanceExists() )
{
- gFloaterCustomize->wearablesChanged(item->getWearableType());
+ LLFloaterCustomize::getInstance()->wearablesChanged(item->getWearableType());
}
return true;
@@ -2243,10 +2022,10 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
{
if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return;
- LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+ LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
- LLPointer cb = wear ? new LLWearAndEditCallback : NULL;
+ LLPointer cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;
LLUUID folder_id;
if (parent_id.notNull())
@@ -2276,7 +2055,7 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
- LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
+ LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
{
llwarns << "Cannot get wearable" << llendl;
@@ -2289,16 +2068,10 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
- //const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(wearable->getType());
+ const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(wearable->getType());
// Set the tab to the right wearable.
- LLFloaterCustomize::setCurrentWearableType( wearable->getType() );
-
- if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() )
- {
- // Start Avatar Customization
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
+ LLFloaterCustomize::editWearable( wearable, disable_camera_switch );
}
// Request editing the item after it gets worn.
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index c3aad9500..b6738604d 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -36,16 +36,16 @@
// newview
#include "llinventorymodel.h"
#include "llviewerinventory.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llwearabledata.h"
class LLInventoryItem;
class LLVOAvatarSelf;
-class LLWearable;
+class LLViewerWearable;
class LLInitialWearablesFetch;
class LLViewerObject;
-class LLTexLayerTemplate;
-class LLAgentWearables : public LLInitClass
+class LLAgentWearables : public LLInitClass, public LLWearableData
{
//--------------------------------------------------------------------
// Constructors / destructors / Initializers
@@ -82,10 +82,10 @@ public:
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
void updateWearablesLoaded();
void checkWearablesLoaded() const;
- bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
+ bool canMoveWearable(const LLUUID& item_id, bool closer_to_body) const;
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
- bool canWearableBeRemoved(const LLWearable* wearable) const;
+ bool canWearableBeRemoved(const LLViewerWearable* wearable) const;
void animateAllWearableParams(F32 delta, BOOL upload_bake);
@@ -99,52 +99,38 @@ public:
// [/RLVa:KB]
const LLUUID getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const;
const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const;
- const LLWearable* getWearableFromItemID(const LLUUID& item_id) const;
- LLWearable* getWearableFromItemID(const LLUUID& item_id);
- LLWearable* getWearableFromAssetID(const LLUUID& asset_id);
+ const LLViewerWearable* getWearableFromItemID(const LLUUID& item_id) const;
+ LLViewerWearable* getWearableFromItemID(const LLUUID& item_id);
+ LLViewerWearable* getWearableFromAssetID(const LLUUID& asset_id);
+ LLViewerWearable* getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/);
+ const LLViewerWearable* getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
LLInventoryItem* getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/);
static BOOL selfHasWearable(LLWearableType::EType type);
- LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
- const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
- LLWearable* getTopWearable(const LLWearableType::EType type);
- LLWearable* getBottomWearable(const LLWearableType::EType type);
- U32 getWearableCount(const LLWearableType::EType type) const;
- U32 getWearableCount(const U32 tex_index) const;
-
- static const U32 MAX_CLOTHING_PER_TYPE = 5;
-
//--------------------------------------------------------------------
// Setters
//--------------------------------------------------------------------
-
private:
- // Low-level data structure setter - public access is via setWearableItem, etc.
- void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
- U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable);
- void wearableUpdated(LLWearable *wearable);
- void popWearable(LLWearable *wearable);
- void popWearable(const LLWearableType::EType type, U32 index);
-
+ /*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed);
public:
- void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
- void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
+ void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
+ void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);
void setWearableName(const LLUUID& item_id, const std::string& new_name);
- void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
- U32 getWearableIndex(const LLWearable *wearable) const;
+ // *TODO: Move this into llappearance/LLWearableData ?
+ void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index);
protected:
- void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
- static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
+ void setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false);
+ static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable);
void addWearableToAgentInventory(LLPointer cb,
- LLWearable* wearable,
+ LLViewerWearable* wearable,
const LLUUID& category_id = LLUUID::null,
BOOL notify = TRUE);
void addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index,
const LLUUID& item_id,
- LLWearable* wearable);
+ LLViewerWearable* wearable);
void recoverMissingWearable(const LLWearableType::EType type, U32 index /*= 0*/);
void recoverMissingWearableDone();
@@ -179,15 +165,15 @@ protected:
public:
// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
- LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
- BOOL generate_valid_hash = TRUE);
protected:
+
+ /*virtual*/ void invalidateBakedTextureHash(LLMD5& hash) const;
void sendAgentWearablesUpdate();
void sendAgentWearablesRequest();
void queryWearableCache();
void updateServer();
- static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
+ static void onInitialWearableAssetArrived(LLViewerWearable* wearable, void* userdata);
//--------------------------------------------------------------------
// Outfits
@@ -205,7 +191,7 @@ private:
// Save Wearables
//--------------------------------------------------------------------
public:
- LLWearable* saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
+ LLViewerWearable* saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
const std::string new_name = "");
void saveAllWearables();
@@ -226,7 +212,6 @@ public:
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false);
// [/SL:KB]
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
- static void userRemoveAllAttachments();
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
BOOL itemUpdatePending(const LLUUID& item_id) const;
@@ -262,10 +247,6 @@ private:
// Member variables
//--------------------------------------------------------------------
private:
- typedef std::vector wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
- typedef std::map wearableentry_map_t; // wearable "categories" arranged by wearable type
- wearableentry_map_t mWearableDatas;
-
static BOOL mInitialWearablesUpdateReceived;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.2.0a
static bool mInitialWearablesLoaded;
@@ -309,13 +290,13 @@ private:
addWearableToAgentInventoryCallback(LLPointer cb,
LLWearableType::EType type,
U32 index,
- LLWearable* wearable,
+ LLViewerWearable* wearable,
U32 todo = CALL_NONE);
virtual void fire(const LLUUID& inv_item);
private:
LLWearableType::EType mType;
U32 mIndex;
- LLWearable* mWearable;
+ LLViewerWearable* mWearable;
U32 mTodo;
LLPointer mCB;
};
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index ec645e9a1..40b311a95 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -40,13 +40,9 @@
#include "rlvhelper.h"
// [/RLVa:KB]
-class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
-{
-public:
- LLOrderMyOutfitsOnDestroy() {};
- virtual ~LLOrderMyOutfitsOnDestroy()
- {
+void order_my_outfits_cb()
+{
if (!LLApp::isRunning())
{
llwarns << "called during shutdown, skipping" << llendl;
@@ -79,15 +75,11 @@ public:
// saved initial outfit already contains wearables ordering information
if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
- LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
- }
-
- llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+ LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
}
- /* virtual */ void fire(const LLUUID& inv_item) {};
-};
-
+ llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+}
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
LLInventoryFetchDescendentsObserver(cof_id)
@@ -634,7 +626,7 @@ void LLLibraryOutfitsFetch::contentsDone()
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
- LLPointer order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
+ LLPointer order_myoutfits_on_destroy = new LLBoostFuncInventoryCallback(no_op_inventory_func, order_my_outfits_cb);
for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
folder_iter != mImportedClothingFolders.end();
diff --git a/indra/newview/llappearance.h b/indra/newview/llappearance.h
index 901815014..05dfac4e4 100644
--- a/indra/newview/llappearance.h
+++ b/indra/newview/llappearance.h
@@ -2,31 +2,25 @@
* @file llappearance.h
* @brief LLAppearance class definition
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -44,14 +38,14 @@ public:
void addParam( S32 id, F32 value ) { mParamMap[id] = value; }
F32 getParam( S32 id, F32 defval ) { return get_if_there(mParamMap, id, defval ); }
- void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLVOAvatarDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
- const LLUUID& getTexture( S32 te ) { return ( te < LLVOAvatarDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
+ void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
+ const LLUUID& getTexture( S32 te ) { return ( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
- void clear() { mParamMap.clear(); for( S32 i=0; i param_map_t;
param_map_t mParamMap;
- LLUUID mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+ LLUUID mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
};
#endif // LL_LLAPPEARANCE_H
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index a3439995e..5947ff919 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -46,8 +46,10 @@
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llviewerregion.h"
+#include "llviewerstats.h"
#include "llwearablelist.h"
#include "llinventorypanel.h"
+#include "llfloatercustomize.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvhelper.h"
@@ -161,81 +163,343 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string
}
}
-class LLWearInventoryCategoryCallback : public LLInventoryCallback
+class LLCallAfterInventoryBatchMgr: public LLEventTimer
{
public:
- LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append)
+ LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id,
+ const std::string& phase_name,
+ nullary_func_t on_completion_func,
+ nullary_func_t on_failure_func = no_op,
+ F32 retry_after = 15.0,
+ S32 max_retries = 2
+ ):
+ mDstCatID(dst_cat_id),
+ mTrackingPhase(phase_name),
+ mOnCompletionFunc(on_completion_func),
+ mOnFailureFunc(on_failure_func),
+ mRetryAfter(retry_after),
+ mMaxRetries(max_retries),
+ mPendingRequests(0),
+ mFailCount(0),
+ mCompletionOrFailureCalled(false),
+ mRetryCount(0),
+ LLEventTimer(retry_after)
{
- mCatID = cat_id;
- mAppend = append;
-
- LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
- }
- void fire(const LLUUID& item_id)
- {
- /*
- * Do nothing. We only care about the destructor
- *
- * The reason for this is that this callback is used in a hack where the
- * same callback is given to dozens of items, and the destructor is called
- * after the last item has fired the event and dereferenced it -- if all
- * the events actually fire!
- */
- LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL;
- }
-
-protected:
- ~LLWearInventoryCategoryCallback()
- {
- LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL;
-
- // Is the destructor called by ordinary dereference, or because the app's shutting down?
- // If the inventory callback manager goes away, we're shutting down, no longer want the callback.
- if( LLInventoryCallbackManager::is_instantiated() )
+ if (!mTrackingPhase.empty())
{
- LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend);
+ //selfStartPhase(mTrackingPhase);
+ }
+ }
+
+ void addItems(LLInventoryModel::item_array_t& src_items)
+ {
+ for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin();
+ it != src_items.end();
+ ++it)
+ {
+ LLViewerInventoryItem* item = *it;
+ llassert(item);
+ addItem(item->getUUID());
+ }
+ }
+
+ // Request or re-request operation for specified item.
+ void addItem(const LLUUID& item_id)
+ {
+ LLUUID linked_id;
+ if (gInventory.getItem(item_id))
+ {
+ linked_id = gInventory.getItem(item_id)->getLinkedUUID();
+ }
+ else if (gInventory.getCategory(item_id))
+ {
+ linked_id = item_id;
}
else
{
- llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
+ llwarns << "no referent found for item_id " << item_id << llendl;
+ return;
+ }
+ LL_DEBUGS("Avatar") << "item_id " << item_id << " -> linked_id " << linked_id << llendl;
+
+ if (ll_frand()::iterator it = mWaitTimes.begin();
+ it != mWaitTimes.end();)
+ {
+ // Use a copy of iterator because it may be erased/invalidated.
+ std::map::iterator curr_it = it;
+ ++it;
+
+ F32 time_waited = curr_it->second.getElapsedTimeF32();
+ S32 retries = mRetryCounts[curr_it->first];
+ if (time_waited > mRetryAfter)
+ {
+ if (retries < mMaxRetries)
+ {
+ LL_DEBUGS("Avatar") << "Waited " << time_waited <<
+ " for " << curr_it->first << ", retrying" << llendl;
+ mRetryCount++;
+ addItem(curr_it->first);
+ }
+ else
+ {
+ llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl;
+ mWaitTimes.erase(curr_it);
+ mFailCount++;
+ }
+ }
+ if (mWaitTimes.empty())
+ {
+ onCompletionOrFailure();
+ }
+
+ }
+ }
+ return all_done;
+ }
+
+ void reportStats()
+ {
+ LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << llendl;
+ LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl;
+ LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl;
+ LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl;
+ LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl;
+ }
+
+ virtual ~LLCallAfterInventoryBatchMgr()
+ {
+ LL_DEBUGS("Avatar") << "deleting" << llendl;
+ }
+
+protected:
+ std::string mTrackingPhase;
+ std::map mWaitTimes;
+ std::map mRetryCounts;
+ LLUUID mDstCatID;
+ nullary_func_t mOnCompletionFunc;
+ nullary_func_t mOnFailureFunc;
+ F32 mRetryAfter;
+ S32 mMaxRetries;
+ S32 mPendingRequests;
+ S32 mFailCount;
+ S32 mRetryCount;
+ bool mCompletionOrFailureCalled;
+ LLViewerStats::StatsAccumulator mTimeStats;
};
-
-//Inventory callback updating "dirty" state when destroyed
-class LLUpdateDirtyState: public LLInventoryCallback
+class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr
{
public:
- LLUpdateDirtyState() {}
- virtual ~LLUpdateDirtyState()
+ LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items,
+ const LLUUID& dst_cat_id,
+ const std::string& phase_name,
+ nullary_func_t on_completion_func,
+ nullary_func_t on_failure_func = no_op,
+ F32 retry_after = 15.0,
+ S32 max_retries = 2
+ ):
+ LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
{
- if (LLAppearanceMgr::instanceExists())
- {
- LLAppearanceMgr::getInstance()->updateIsDirty();
- }
+ addItems(src_items);
+ }
+
+ virtual bool requestOperation(const LLUUID& item_id)
+ {
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ llassert(item);
+ LL_DEBUGS("Avatar") << "copying item " << item_id << llendl;
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ mDstCatID,
+ std::string(),
+ new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))
+ );
+ return true;
}
- virtual void fire(const LLUUID&) {}
};
+class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr
+{
+public:
+ LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items,
+ const LLUUID& dst_cat_id,
+ const std::string& phase_name,
+ nullary_func_t on_completion_func,
+ nullary_func_t on_failure_func = no_op,
+ F32 retry_after = 15.0,
+ S32 max_retries = 2
+ ):
+ LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+ {
+ addItems(src_items);
+ }
+
+ virtual bool requestOperation(const LLUUID& item_id)
+ {
+ bool request_sent = false;
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item)
+ {
+ LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
+ // create an inventory item link.
+ link_inventory_item(gAgent.getID(),
+ item_id,
+ mDstCatID,
+ item->getName(),
+ item->LLInventoryItem::getDescription(),
+ LLAssetType::AT_LINK,
+ new LLBoostFuncInventoryCallback(
+ boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+ request_sent = true;
+ }
+ else
+ {
+ // create a base outfit link if appropriate.
+ LLViewerInventoryCategory *catp = gInventory.getCategory(item_id);
+ if (!catp)
+ {
+ llwarns << "id not found as inventory item or category " << item_id << llendl;
+ return false;
+ }
+ const LLUUID cof = LLAppearanceMgr::instance().getCOF();
+ std::string new_outfit_name = "";
+
+ LLAppearanceMgr::instance().purgeBaseOutfitLink(cof);
+
+ if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+ {
+ LL_DEBUGS("Avatar") << "linking folder " << item_id << " name " << catp->getName() << " to cof " << cof << llendl;
+ link_inventory_item(gAgent.getID(), item_id, cof, catp->getName(), "",
+ LLAssetType::AT_LINK_FOLDER,
+ new LLBoostFuncInventoryCallback(
+ boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+ new_outfit_name = catp->getName();
+ request_sent = true;
+ }
+
+ LLAppearanceMgr::instance().updatePanelOutfitName(new_outfit_name);
+ }
+ return request_sent;
+ }
+};
LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering):
mFireCount(0),
mUpdateBaseOrder(update_base_outfit_ordering)
{
+ //selfStartPhase("update_appearance_on_destroy");
}
LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
{
- LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
- llinfos << "done update appearance on destroy" << llendl;
-
if (!LLApp::isExiting())
{
+ // speculative fix for MAINT-1150
+ LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
+
+ //selfStopPhase("update_appearance_on_destroy");
+
LLAppearanceMgr::instance().updateAppearanceFromCOF(mUpdateBaseOrder);
}
}
@@ -277,7 +541,7 @@ struct LLFoundData
std::string mName;
LLAssetType::EType mAssetType;
LLWearableType::EType mWearableType;
- LLWearable* mWearable;
+ LLViewerWearable* mWearable;
bool mIsReplacement;
};
@@ -301,7 +565,7 @@ public:
void recoverMissingWearable(LLWearableType::EType type);
void clearCOFLinksForMissingWearables();
- void onWearableAssetFetch(LLWearable *wearable);
+ void onWearableAssetFetch(LLViewerWearable *wearable);
void onAllComplete();
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a
@@ -331,7 +595,7 @@ private:
typedef std::set type_set_hp;
static type_set_hp sActiveHoldingPatterns;
bool mIsMostRecent;
- std::set mLateArrivals;
+ std::set mLateArrivals;
bool mIsAllComplete;
};
@@ -359,11 +623,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern():
}
sActiveHoldingPatterns.insert(this);
+ //selfStartPhase("holding_pattern");
}
LLWearableHoldingPattern::~LLWearableHoldingPattern()
{
sActiveHoldingPatterns.erase(this);
+ if (isMostRecent())
+ {
+ //selfStopPhase("holding_pattern");
+ }
}
bool LLWearableHoldingPattern::isMostRecent()
@@ -452,6 +721,8 @@ void LLWearableHoldingPattern::checkMissingWearables()
}
resetTime(60.0F);
+
+ //selfStartPhase("get_missing_wearables");
if (!pollMissingWearables())
{
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this));
@@ -516,6 +787,8 @@ void LLWearableHoldingPattern::onAllComplete()
void LLWearableHoldingPattern::onFetchCompletion()
{
+ //selfStopPhase("get_wearables");
+
if (!isMostRecent())
{
// runway skip here?
@@ -561,104 +834,77 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
return done;
}
-class RecoveredItemLinkCB: public LLInventoryCallback
+void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
{
-public:
- RecoveredItemLinkCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
- mHolder(holder),
- mWearable(wearable),
- mType(type)
+ if (!holder->isMostRecent())
{
+ llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
}
- void fire(const LLUUID& item_id)
+
+ llinfos << "Recovered item link for type " << type << llendl;
+ holder->eraseTypeToLink(type);
+ // Add wearable to FoundData for actual wearing
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+
+ if (linked_item)
{
- if (!mHolder->isMostRecent())
- {
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
- }
-
- llinfos << "Recovered item link for type " << mType << llendl;
- mHolder->eraseTypeToLink(mType);
- // Add wearable to FoundData for actual wearing
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
-
- if (linked_item)
- {
- gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
- if (item)
- {
- LLFoundData found(linked_item->getUUID(),
- linked_item->getAssetUUID(),
- linked_item->getName(),
- linked_item->getType(),
- linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
- true // is replacement
- );
- found.mWearable = mWearable;
- mHolder->getFoundList().push_front(found);
- }
- else
- {
- llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
- }
+ if (item)
+ {
+ LLFoundData found(linked_item->getUUID(),
+ linked_item->getAssetUUID(),
+ linked_item->getName(),
+ linked_item->getType(),
+ linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
+ true // is replacement
+ );
+ found.mWearable = wearable;
+ holder->getFoundList().push_front(found);
}
else
{
- llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
+ llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
}
}
-private:
- LLWearableHoldingPattern* mHolder;
- LLWearable *mWearable;
- LLWearableType::EType mType;
-};
-
-class RecoveredItemCB: public LLInventoryCallback
-{
-public:
- RecoveredItemCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
- mHolder(holder),
- mWearable(wearable),
- mType(type)
+ else
{
+ llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
}
- void fire(const LLUUID& item_id)
+}
+
+void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
+{
+ if (!holder->isMostRecent())
{
- if (!mHolder->isMostRecent())
- {
- // runway skip here?
- llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a
- // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
- return;
+ // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
+ return;
// [/SL:KB]
- }
-
- LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL;
- LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
- mWearable->setItemID(item_id);
- LLPointer cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
- mHolder->eraseTypeToRecover(mType);
- llassert(itemp);
- if (itemp)
- {
- link_inventory_item( gAgent.getID(),
- item_id,
- LLAppearanceMgr::instance().getCOF(),
- itemp->getName(),
- itemp->getDescription(),
- LLAssetType::AT_LINK,
- cb);
- }
}
-private:
- LLWearableHoldingPattern* mHolder;
- LLWearable *mWearable;
- LLWearableType::EType mType;
-};
+
+ LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
+ LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+ wearable->setItemID(item_id);
+ LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
+ holder->eraseTypeToRecover(type);
+ llassert(itemp);
+ if (itemp)
+ {
+ link_inventory_item( gAgent.getID(),
+ item_id,
+ LLAppearanceMgr::instance().getCOF(),
+ itemp->getName(),
+ itemp->getDescription(),
+ LLAssetType::AT_LINK,
+ cb);
+ }
+}
void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
{
@@ -672,11 +918,11 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type
LLNotificationsUtil::add("ReplacedMissingWearable");
lldebugs << "Wearable " << LLWearableType::getTypeLabel(type)
<< " could not be downloaded. Replaced inventory item with default wearable." << llendl;
- LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+ LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
// Add a new one in the lost and found folder.
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
- LLPointer cb = new RecoveredItemCB(type,wearable,this);
+ LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
create_inventory_item(gAgent.getID(),
gAgent.getSessionID(),
@@ -705,7 +951,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
{
// Wearable link that was never resolved; remove links to it from COF
LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
- LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+ LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
}
}
}
@@ -752,6 +998,8 @@ bool LLWearableHoldingPattern::pollMissingWearables()
if (done)
{
+ //selfStopPhase("get_missing_wearables");
+
gAgentAvatarp->debugWearablesLoaded();
// BAP - if we don't call clearCOFLinksForMissingWearables()
@@ -796,11 +1044,11 @@ void LLWearableHoldingPattern::handleLateArrivals()
iter != getFoundList().end(); ++iter)
{
LLFoundData& data = *iter;
- for (std::set::iterator wear_it = mLateArrivals.begin();
+ for (std::set::iterator wear_it = mLateArrivals.begin();
wear_it != mLateArrivals.end();
++wear_it)
{
- LLWearable *wearable = *wear_it;
+ LLViewerWearable *wearable = *wear_it;
if(wearable->getAssetID() == data.mAssetID)
{
@@ -836,7 +1084,7 @@ void LLWearableHoldingPattern::handleLateArrivals()
if (data.mWearable && data.mIsReplacement &&
replaced_types.find(data.mWearableType) != replaced_types.end())
{
- LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+ LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
std::list::iterator clobber_ator = iter;
++iter;
getFoundList().erase(clobber_ator);
@@ -860,7 +1108,7 @@ void LLWearableHoldingPattern::resetTime(F32 timeout)
mWaitTime.setTimerExpirySec(timeout);
}
-void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
+void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)
{
if (!isMostRecent())
{
@@ -911,7 +1159,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
}
}
-static void onWearableAssetFetch(LLWearable* wearable, void* data)
+static void onWearableAssetFetch(LLViewerWearable* wearable, void* data)
{
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
holder->onWearableAssetFetch(wearable);
@@ -967,6 +1215,18 @@ const LLUUID LLAppearanceMgr::getCOF() const
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
+S32 LLAppearanceMgr::getCOFVersion() const
+{
+ LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
+ if (cof)
+ {
+ return cof->getVersion();
+ }
+ else
+ {
+ return LLViewerInventoryCategory::VERSION_UNKNOWN;
+ }
+}
const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
{
@@ -1035,6 +1295,18 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID()
return outfit_cat->getUUID();
}
+void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace/*= false*/)
+{
+ if (inv_item.isNull())
+ return;
+
+ LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace);
+ }
+}
+
bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace, LLPointer cb)
{
if (item_id_to_wear.isNull()) return false;
@@ -1054,8 +1326,8 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
{
- LLPointer cb = new WearOnAvatarCallback(replace);
- copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);
+ LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&wear_on_avatar_cb,_1,replace));
+ copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb);
return false;
}
else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID()))
@@ -1108,7 +1380,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
if ((replace && wearable_count != 0) ||
(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
{
- removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false);
+ removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1));
}
addCOFItemLink(item_to_wear, do_update, cb);
}
@@ -1118,7 +1390,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
// Remove the existing wearables of the same type.
// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
- removeCOFLinksOfType(item_to_wear->getWearableType(), false);
+ removeCOFLinksOfType(item_to_wear->getWearableType());
addCOFItemLink(item_to_wear, do_update, cb);
break;
@@ -1216,11 +1488,13 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
LLInventoryModel::item_array_t::const_iterator it = items.begin();
const LLInventoryModel::item_array_t::const_iterator it_end = items.end();
+ uuid_vec_t uuids_to_remove;
for( ; it_end != it; ++it)
{
LLViewerInventoryItem* item = *it;
- removeItemFromAvatar(item->getUUID());
+ uuids_to_remove.push_back(item->getUUID());
}
+ removeItemsFromAvatar(uuids_to_remove);
}
// Create a copy of src_id + contents as a subfolder of dst_id.
@@ -1488,7 +1762,7 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin
}
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
-void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLPointer cb)
+void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter)
{
const LLUUID idCOF = getCOF();
LLInventoryModel::item_array_t cur_cof_items, new_cof_items = items;
@@ -1519,9 +1793,7 @@ void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAss
// Link to whatever remains in new_cof_items
for (S32 idxNewItem = 0, cntNewItem = new_cof_items.count(); idxNewItem < cntNewItem; idxNewItem++)
{
- const LLInventoryItem* pItem = new_cof_items.get(idxNewItem);
- link_inventory_item(
- gAgent.getID(), pItem->getLinkedUUID(), idCOF, pItem->getName(), pItem->LLInventoryItem::getDescription(), LLAssetType::AT_LINK, cb);
+ link_waiter->addItem(new_cof_items.get(idxNewItem)->getLinkedUUID());
}
}
// [/SL:KB]
@@ -1594,7 +1866,7 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
LLInventoryModel::item_array_t& wear_items_new,
LLInventoryModel::item_array_t& obj_items_new,
LLInventoryModel::item_array_t& gest_items_new,
- bool append /*=false*/, const LLUUID& idOutfit /*=LLUUID::null*/)
+ bool append /*=false*/, const LLUUID& category /*=LLUUID::null*/)
// [/RLVa:KB]
{
// LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
@@ -1703,37 +1975,37 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
// [/RLVa:KB]
removeDuplicateItems(gest_items);
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
+#endif
+
// Create links to new COF contents.
- LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL;
- LLPointer link_waiter = new LLUpdateAppearanceOnDestroy(!append);
+ LL_DEBUGS("Avatar") << self_av_string() << "creating LLCallAfterInventoryLinkMgr" << LL_ENDL;
+ bool update_base_outfit_ordering = !append;
+ LLCallAfterInventoryLinkMgr *link_waiter =
+ new LLCallAfterInventoryLinkMgr(body_items,cof,"update_appearance_on_destroy",
+ boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF,
+ LLAppearanceMgr::getInstance(),
+ update_base_outfit_ordering));
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
if (!append)
{
// [/SL:KB]
- // Remove current COF contents.
- bool keep_outfit_links = append;
- purgeCategory(cof, keep_outfit_links);
- gInventory.notifyObservers();
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
-#endif
- linkAll(cof, body_items, link_waiter);
-
#ifndef LL_RELEASE_FOR_DOWNLOAD
LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL;
#endif
- linkAll(cof, wear_items, link_waiter);
+ link_waiter->addItems(wear_items);
#ifndef LL_RELEASE_FOR_DOWNLOAD
LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL;
#endif
- linkAll(cof, obj_items, link_waiter);
+ link_waiter->addItems(obj_items);
#ifndef LL_RELEASE_FOR_DOWNLOAD
LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL;
#endif
- linkAll(cof, gest_items, link_waiter);
+ link_waiter->addItems(gest_items);
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
}
else
@@ -1744,21 +2016,25 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
syncCOF(wear_items, LLAssetType::AT_CLOTHING, link_waiter);
syncCOF(obj_items, LLAssetType::AT_OBJECT, link_waiter);
syncCOF(gest_items, LLAssetType::AT_GESTURE, link_waiter);
- gInventory.notifyObservers();
}
// [/SL:KB]
// Add link to outfit if category is an outfit.
-// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Added: RLVa-1.2.0b
- if ( (!append) && (idOutfit.notNull()) )
- {
- createBaseOutfitLink(idOutfit, link_waiter);
- }
+// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.0b
+ if (!append && category.notNull())
// [/RLVa:KB]
// if (!append)
-// {
-// createBaseOutfitLink(category, link_waiter);
-// }
+ {
+ link_waiter->addItem(category);
+ }
+
+ // Remove current COF contents. Have to do this after creating
+ // the link_waiter so links can be followed for any items that get
+ // carried over (e.g. keeping old shape if the new outfit does not
+ // contain one)
+ bool keep_outfit_links = append;
+ purgeCategory(cof, keep_outfit_links);
+ gInventory.notifyObservers();
LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
}
@@ -1796,7 +2072,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
{
lldebugs << "updateAgentWearables()" << llendl;
LLInventoryItem::item_array_t items;
- LLDynamicArray< LLWearable* > wearables;
+ LLDynamicArray< LLViewerWearable* > wearables;
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
uuid_vec_t idsCurrent; LLInventoryModel::item_array_t itemsNew;
if (rlv_handler_t::isEnabled())
@@ -1813,7 +2089,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
iter != holder->getFoundList().end(); ++iter)
{
LLFoundData& data = *iter;
- LLWearable* wearable = data.mWearable;
+ LLViewerWearable* wearable = data.mWearable;
if( wearable && ((S32)wearable->getType() == i) )
{
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
@@ -1862,7 +2138,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
// We need to report removals before additions or scripts will get confused
for (uuid_vec_t::const_iterator itItemID = idsCurrent.begin(); itItemID != idsCurrent.end(); ++itItemID)
{
- const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID);
+ const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID);
if (pWearable)
RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true);
}
@@ -2004,6 +2280,15 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
// the saved outfit stored as a folder link
updateIsDirty();
+ // Send server request for appearance update
+ if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+ {
+ requestServerAppearanceUpdate();
+ }
+ // DRANO really should wait for the appearance message to set this.
+ // verify that deleting this line doesn't break anything.
+ gAgentAvatarp->setIsUsingServerBakes(gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion());
+
//dumpCat(getCOF(),"COF, start");
bool follow_folder_links = true;
@@ -2139,6 +2424,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
}
}
+ //selfStartPhase("get_wearables");
+
for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();
it != holder->getFoundList().end(); ++it)
{
@@ -2149,6 +2436,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
// Fetch the wearables about to be worn.
LLWearableList::instance().getAsset(found.mAssetID,
found.mName,
+ gAgentAvatarp,
found.mAssetType,
onWearableAssetFetch,
(void*)holder);
@@ -2231,11 +2519,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
{
if(!category) return;
+ //selfClearPhases();
+ //selfStartPhase("wear_inventory_category");
+
gAgentWearables.notifyLoadingStarted();
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName()
<< " )" << LL_ENDL;
+ //selfStartPhase("wear_inventory_category_fetch");
callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
&LLAppearanceMgr::instance(),
category->getUUID(), copy, append));
@@ -2244,6 +2536,8 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
{
LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+
+ //selfStopPhase("wear_inventory_category_fetch");
// We now have an outfit ready to be copied to agent inventory. Do
// it, and wear that outfit normally.
@@ -2292,22 +2586,15 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap
pid,
LLFolderType::FT_NONE,
name);
- LLPointer cb = new LLWearInventoryCategoryCallback(new_cat_id, append);
- it = items->begin();
- for(; it < end; ++it)
- {
- item = *it;
- if(item)
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- new_cat_id,
- std::string(),
- cb);
- }
- }
+
+ // Create a CopyMgr that will copy items, manage its own destruction
+ new LLCallAfterInventoryCopyMgr(
+ *items, new_cat_id, std::string("wear_inventory_category_callback"),
+ boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar,
+ LLAppearanceMgr::getInstance(),
+ gInventory.getCategory(new_cat_id),
+ append));
+
// BAP fixes a lag in display of created dir.
gInventory.notifyObservers();
}
@@ -2324,12 +2611,18 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
// Avoid unintentionally overwriting old wearables. We have to do
// this up front to avoid having to deal with the case of multiple
// wearables being dirty.
- if(!category) return;
+ if (!category) return;
+
+ if ( !LLInventoryCallbackManager::is_instantiated() )
+ {
+ // shutting down, ignore.
+ return;
+ }
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
<< "'" << LL_ENDL;
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
{
// switching to outfit editor should automagically save any currently edited wearable
//LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); // MULTI-WEARABLES TODO
@@ -2439,6 +2732,25 @@ void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPo
}
}
+void modified_cof_cb(const LLUUID& inv_item)
+{
+ LLAppearanceMgr::instance().updateAppearanceFromCOF();
+
+ // Start editing the item if previously requested.
+ gAgentWearables.editWearableIfRequested(inv_item);
+
+ // TODO: camera mode may not be changed if a debug setting is tweaked
+ if( LLFloaterCustomize::instanceExists() )
+ {
+ // If we're in appearance editing mode, the current tab may need to be refreshed
+ /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance"));
+ if (panel)
+ {
+ panel->showDefaultSubpart();
+ }*/
+ LLFloaterCustomize::getInstance()->switchToDefaultSubpart();
+ }
+}
void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer cb)
{
const LLViewerInventoryItem *vitem = dynamic_cast(item);
@@ -2509,12 +2821,12 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
{
if(do_update && cb.isNull())
{
- cb = new ModifiedCOFCallback;
+ cb = new LLBoostFuncInventoryCallback(modified_cof_cb);
}
std::string description = vitem->getIsLinkType() ? vitem->getDescription() : "";
if(description.empty())
{
- LLWearable* wearable = gAgentWearables.getWearableFromItemID(vitem->getLinkedUUID());
+ LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(vitem->getLinkedUUID());
if(wearable)
{
U32 index = gAgentWearables.getWearableIndex(wearable);
@@ -2537,23 +2849,67 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
return;
}
-// BAP remove ensemble code for 2.1?
-void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update )
+void LLAppearanceMgr::removeAllClothesFromAvatar()
{
-#if SUPPORT_ENSEMBLES
- // BAP add check for already in COF.
- LLPointer cb = do_update ? new ModifiedCOFCallback : 0;
- link_inventory_item( gAgent.getID(),
- cat->getLinkedUUID(),
- getCOF(),
- cat->getName(),
- cat->getDescription(),
- LLAssetType::AT_LINK_FOLDER,
- cb);
-#endif
+ // Fetch worn clothes (i.e. the ones in COF).
+ LLInventoryModel::item_array_t clothing_items;
+ LLInventoryModel::cat_array_t dummy;
+ LLIsType is_clothing(LLAssetType::AT_CLOTHING);
+ gInventory.collectDescendentsIf(getCOF(),
+ dummy,
+ clothing_items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_clothing,
+ false);
+ uuid_vec_t item_ids;
+ // Take them off by removing from COF.
+ for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin();
+ it != clothing_items.end(); ++it)
+ {
+// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
+ if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(*it)) )
+ continue;
+// [/RLVa:KB]
+ item_ids.push_back((*it).get()->getLinkedUUID());
+ }
+
+ // Take them off by removing from COF.
+ removeItemsFromAvatar(item_ids);
}
-void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
+void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
+{
+ if (!isAgentAvatarValid()) return;
+
+ LLAgentWearables::llvo_vec_t objects_to_remove;
+
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end();)
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *attached_object = (*attachment_iter);
+ if (attached_object)
+ {
+ objects_to_remove.push_back(attached_object);
+ }
+ }
+ }
+ uuid_vec_t ids_to_remove;
+ for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin();
+ it != objects_to_remove.end();
+ ++it)
+ {
+ ids_to_remove.push_back((*it)->getAttachmentItemID());
+ }
+ removeItemsFromAvatar(ids_to_remove);
+}
+
+void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
@@ -2571,13 +2927,9 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
gInventory.purgeObject(item->getUUID());
}
}
- if (do_update)
- {
- LLAppearanceMgr::updateAppearanceFromCOF();
- }
}
-void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_update)
+void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type)
{
LLFindWearablesOfType filter_wearables_of_type(type);
LLInventoryModel::cat_array_t cats;
@@ -2593,11 +2945,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_u
gInventory.purgeObject(item->getUUID());
}
}
-
- if (do_update)
- {
- updateAppearanceFromCOF();
- }
}
bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
@@ -2734,7 +3081,7 @@ void LLAppearanceMgr::copyLibraryGestures()
folder_name == COMMON_GESTURES_FOLDER ||
folder_name == OTHER_GESTURES_FOLDER)
{
- cb = new ActivateGestureCallback;
+ cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
}
LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
@@ -2788,6 +3135,16 @@ void LLAppearanceMgr::onFirstFullyVisible()
}
}
+// update "dirty" state - defined outside class to allow for calling
+// after appearance mgr instance has been destroyed.
+void appearance_mgr_update_dirty_state()
+{
+ if (LLAppearanceMgr::instanceExists())
+ {
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ }
+}
+
bool LLAppearanceMgr::updateBaseOutfit()
{
if (isOutfitLocked())
@@ -2808,8 +3165,8 @@ bool LLAppearanceMgr::updateBaseOutfit()
// in a Base Outfit we do not remove items, only links
purgeCategory(base_outfit_id, false);
-
- LLPointer dirty_state_updater = new LLUpdateDirtyState();
+ LLPointer dirty_state_updater =
+ new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
//COF contains only links so we copy to the Base Outfit only links
shallowCopyCategoryContents(getCOF(), base_outfit_id, dirty_state_updater);
@@ -2940,79 +3297,206 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
if (inventory_changed) gInventory.notifyObservers();
}
-
-
-class LLScrollOnFirstItem : public LLInventoryCallback
+// This is intended for use with HTTP Clients/Responders, but is not
+// specifically coupled with those classes.
+class LLHTTPRetryPolicy: public LLThreadSafeRefCount
{
public:
- LLScrollOnFirstItem(const LLUUID&folder_id, bool do_scroll) : mFirstItemCreated(!do_scroll), mFolderID(folder_id)
- {}
-
- virtual void fire(const LLUUID& item_id)
- {
- if(mFirstItemCreated)
- return;
- mFirstItemCreated = true;
- if (LLInventoryPanel::getActiveInventoryPanel())
- {
- if( LLFolderView* root = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder())
- {
- LLFolderViewItem* folder = dynamic_cast(root->getItemByID(mFolderID));
- if(folder)
- {
- folder->openItem();
- root->setSelection(folder,true,false);
- root->scrollToShowSelection();
- }
- }
- }
- }
- bool mFirstItemCreated;
- LLUUID mFolderID;
+ LLHTTPRetryPolicy() {}
+ virtual ~LLHTTPRetryPolicy() {}
+ virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0;
};
-class LLShowCreatedOutfit: public LLScrollOnFirstItem
+// Example of simplest possible policy, not necessarily recommended.
+class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy
{
public:
- LLShowCreatedOutfit(const LLUUID& folder_id, bool show_panel = true): LLScrollOnFirstItem(folder_id, show_panel), mFolderID(folder_id), mShowPanel(show_panel)
- {}
-
- virtual ~LLShowCreatedOutfit()
+ LLAlwaysRetryImmediatelyPolicy() {}
+ bool shouldRetry(U32 status, F32& seconds_to_wait)
{
- if (!LLApp::isRunning())
- {
- llwarns << "called during shutdown, skipping" << llendl;
- return;
- }
+ seconds_to_wait = 0.0;
+ return true;
+ }
+};
- LLSD key;
+// Very general policy with geometric back-off after failures,
+// up to a maximum delay, and maximum number of retries.
+class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
+{
+public:
+ LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries):
+ mMinDelay(min_delay),
+ mMaxDelay(max_delay),
+ mBackoffFactor(backoff_factor),
+ mMaxRetries(max_retries),
+ mDelay(min_delay),
+ mRetryCount(0)
+ {
+ }
+
+ bool shouldRetry(U32 status, F32& seconds_to_wait)
+ {
+ seconds_to_wait = mDelay;
+ mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
+ mRetryCount++;
+ return (mRetryCount<=mMaxRetries);
+ }
+
+private:
+ F32 mMinDelay; // delay never less than this value
+ F32 mMaxDelay; // delay never exceeds this value
+ F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay.
+ U32 mMaxRetries; // maximum number of times shouldRetry will return true.
+ F32 mDelay; // current delay.
+ U32 mRetryCount; // number of times shouldRetry has been called.
+};
+
+extern AIHTTPTimeoutPolicy requestAgentUpdateAppearance_timeout;
+class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::ResponderWithResult
+{
+public:
+ virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return requestAgentUpdateAppearance_timeout; }
+ RequestAgentUpdateAppearanceResponder()
+ {
+ mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5);
+ }
+
+ virtual ~RequestAgentUpdateAppearanceResponder()
+ {
+ }
+
+ // Successful completion.
+ /* virtual */ void result(const LLSD& content)
+ {
+ llinfos << "request OK" << llendl;
+ }
+
+ // Error
+ /*virtual*/ void error(U32 status, const std::string& reason)
+ {
+ llwarns << "appearance update request failed, status: " << status << " reason: " << reason << llendl;
+ F32 seconds_to_wait;
+ if (mRetryPolicy->shouldRetry(status,seconds_to_wait))
+ {
+ llinfos << "retrying" << llendl;
+ doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate,
+ LLAppearanceMgr::getInstance(),
+ LLHTTPClient::ResponderPtr(this)),
+ seconds_to_wait);
+ }
+ else
+ {
+ llwarns << "giving up after too many retries" << llendl;
+ }
+ }
+
+ LLPointer mRetryPolicy;
+
+ /*virtual*/ char const* getName(void) const { return "RequestAgentUpdateAppearanceResponder"; }
+};
+
+void LLAppearanceMgr::requestServerAppearanceUpdate(LLHTTPClient::ResponderPtr responder_ptr)
+{
+ if (!gAgent.getRegion())
+ {
+ llwarns << "Region not set, cannot request server appearance update" << llendl;
+ return; //Avoid a crash here. RequestAgentUpdateAppearanceResponder crams requestServerAppearanceUpdate into an event...
+ //which results in gAgent.getRegion() legitimately returning NULL under some scenarios.
+ }
+ if (gAgent.getRegion()->getCentralBakeVersion()==0)
+ {
+ llwarns << "Region does not support baking" << llendl;
+ }
+ std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");
+ if (url.empty())
+ {
+ llwarns << "No cap for UpdateAvatarAppearance." << llendl;
+ return;
+ }
+
+ LLSD body;
+ S32 cof_version = getCOFVersion();
+ body["cof_version"] = cof_version;
+ LL_DEBUGS("Avatar") << "my_cof_version " << cof_version << llendl;
+
+ //LLHTTPClient::ResponderPtr responder_ptr;
+ if (!responder_ptr.get())
+ {
+ responder_ptr = new RequestAgentUpdateAppearanceResponder;
+ }
+ LLHTTPClient::post(url, body, responder_ptr);
+ llassert(cof_version >= mLastUpdateRequestCOFVersion);
+ mLastUpdateRequestCOFVersion = cof_version;
+}
+
+void show_created_outfit(const LLUUID& folder_id, bool show_panel = true)
+{
+ if (!LLApp::isRunning())
+ {
+ llwarns << "called during shutdown, skipping" << llendl;
+ return;
+ }
+
+ LLSD key;
+
+ //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process
+ // add may be processed after login process is finished
+ // MULTI-WEARABLES TODO
+ /*if (mShowPanel)
+ {
+ LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
- //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process
- // add may be processed after login process is finished
- // MULTI-WEARABLES TODO
- /*if (mShowPanel)
- {
- LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
-
- }
- LLOutfitsList *outfits_list =
- dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
- if (outfits_list)
- {
- outfits_list->setSelectedOutfitByUUID(mFolderID);
- }*/
-
- LLAppearanceMgr::getInstance()->updateIsDirty();
- gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
- LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
}
+ LLOutfitsList *outfits_list =
+ dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
+ if (outfits_list)
+ {
+ outfits_list->setSelectedOutfitByUUID(mFolderID);
+ }*/
-protected:
- LLUUID mFolderID;
- bool mShowPanel;
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
+ LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
+}
+
+void scroll_to_folder(const LLUUID& folder_id)
+{
+ if (LLInventoryPanel::getActiveInventoryPanel())
+ {
+ if( LLFolderView* root = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder())
+ {
+ LLFolderViewItem* item = root->getItemByID(folder_id);
+ if(!root)
+ return;
+ LLFolderViewFolder* folder = dynamic_cast(item);
+ if(folder)
+ {
+ folder->openItem();
+ }
+ root->setSelection(item,true,false);
+ root->scrollToShowSelection();
+ }
+ }
+}
+
+class LLBoostFuncInventoryCallbackFireOnce : public LLBoostFuncInventoryCallback
+{
+public:
+ LLBoostFuncInventoryCallbackFireOnce(inventory_func_type fire_func, nullary_func_type destroy_func = no_op) :
+ LLBoostFuncInventoryCallback(fire_func, destroy_func), mFired(false)
+ {}
+private:
+ void fire(const LLUUID& item_id)
+ {
+ if(mFired)
+ return;
+ mFired = true;
+ LLBoostFuncInventoryCallback::fire(item_id);
+ }
+ bool mFired;
};
-LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
+LLUUID LLAppearanceMgr::makeNewOutfitCore(const std::string& new_folder_name, bool show_panel, LLInventoryModel::item_array_t* items /*=NULL*/)
{
if (!isAgentAvatarValid()) return LLUUID::null;
@@ -3027,39 +3511,34 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b
updateClothingOrderingInfo();
- LLPointer cb = new LLShowCreatedOutfit(folder_id,show_panel);
- shallowCopyCategoryContents(getCOF(),folder_id, cb);
+ inventory_func_type fire_fn = no_op_inventory_func;
+ if(show_panel)
+ fire_fn = boost::bind(&scroll_to_folder,folder_id);
+
+ LLPointer cb = new LLBoostFuncInventoryCallbackFireOnce( fire_fn,
+ boost::bind(&show_created_outfit,folder_id,show_panel));
+
+ if(items)
+ copyItems(folder_id,items,cb);
+ else
+ shallowCopyCategoryContents(getCOF(),folder_id,cb);
+
createBaseOutfitLink(folder_id, cb);
dumpCat(folder_id,"COF, new outfit");
return folder_id;
}
+LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel/*=true*/)
+{
+ return makeNewOutfitCore(new_folder_name, show_panel);
+}
//Given an array of items from COF. v3 outfit behavior.
-LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool show_panel )
+LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& items)
{
- if (!isAgentAvatarValid()) return LLUUID::null;
- else if (items.empty()) return LLUUID::null;
-
- gAgentWearables.notifyLoadingStarted();
-
- // First, make a folder in the My Outfits directory.
- const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
- LLUUID folder_id = gInventory.createNewCategory(
- parent_id,
- LLFolderType::FT_OUTFIT,
- new_folder_name);
-
- updateClothingOrderingInfo();
-
- LLPointer cb = new LLShowCreatedOutfit(folder_id,show_panel);
- copyItems(folder_id, &items, cb);
- createBaseOutfitLink(folder_id, cb);
-
- dumpCat(folder_id,"COF, new outfit");
-
- return folder_id;
+ if (items.empty()) return LLUUID::null;
+ return makeNewOutfitCore(new_folder_name, true, &items);
}
//Creates item copies before links and ties all requests to a sole handler
@@ -3075,12 +3554,14 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, L
// 2) Stuff with requests via makeLink and makeCopy
// 3) Call dispatch()
// 4) Let the LLPointer go out of scope.
-class LLCreateLegacyOutfit : public LLShowCreatedOutfit
+class LLCreateLegacyOutfit : public LLBoostFuncInventoryCallbackFireOnce
{
public:
- LLCreateLegacyOutfit(const LLUUID& folder_id, bool show_panel) :
- LLShowCreatedOutfit(folder_id, show_panel), mFolderID(folder_id), mFailed(false)
+ LLCreateLegacyOutfit(const LLUUID& folder_id, inventory_func_type fire_func, nullary_func_type destroy_func = no_op) :
+ LLBoostFuncInventoryCallbackFireOnce(fire_func, destroy_func),
+ mFolderID(folder_id), mFailed(false)
{}
+
virtual ~LLCreateLegacyOutfit()
{
if (!LLApp::isRunning() || mFailed)
@@ -3207,7 +3688,7 @@ public:
return;
}
if(item_id.notNull())
- LLShowCreatedOutfit::fire(item_id);
+ show_created_outfit(item_id);
std::vector::iterator it = std::find(mActiveRequests.begin(), mActiveRequests.end(),cb);
if(it != mActiveRequests.end())
@@ -3282,7 +3763,7 @@ private:
//Given an array of items from COF. Will only use links for no-copy, no-mod, or multi-worn clothing.
-LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links, bool show_panel )
+LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links )
{
if (!isAgentAvatarValid()) return LLUUID::null;
else if (items.empty()) return LLUUID::null;
@@ -3301,7 +3782,7 @@ LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name,
LLInventoryModel::item_array_t base_items;
LLInventoryModel::item_array_t remove_items;
- LLPointer cb = new LLCreateLegacyOutfit(folder_id,show_panel);
+ LLPointer cb = new LLCreateLegacyOutfit(folder_id,boost::bind(&scroll_to_folder,folder_id),boost::bind(&show_created_outfit,folder_id,true));
for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();
iter != items.end();
@@ -3337,56 +3818,42 @@ void LLAppearanceMgr::wearBaseOutfit()
updateCOF(base_outfit_id);
}
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
+{
+ if (ids_to_remove.empty())
+ {
+ llwarns << "called with empty list, nothing to do" << llendl;
+ }
+ for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
+ {
+ const LLUUID& id_to_remove = *it;
+ const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+
+ // [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d
+// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.1c
+ LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
+ if (!item_to_remove)
+ continue;
+ if (rlv_handler_t::isEnabled() && !gRlvWearableLocks.canRemove(item_to_remove))
+ continue;
+ if (item_to_remove->getType() == LLAssetType::AT_CLOTHING)
+ {
+ const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID());
+ if(!pWearable || pWearable->getAssetType() == LLAssetType::AT_BODYPART || gAgentWearables.getWearableIndex(pWearable) >= LLAgentWearables::MAX_CLOTHING_PER_TYPE )
+ continue;
+ RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true);
+ }
+// [/RLVa:KB]
+ removeCOFItemLinks(linked_item_id);
+ }
+ updateAppearanceFromCOF();
+}
+
void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
{
- LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
- if (!item_to_remove) return;
-
- switch (item_to_remove->getType())
- {
- case LLAssetType::AT_CLOTHING:
-// if (get_is_item_worn(id_to_remove))
-// {
-// //*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
-// LLWearableBridge::removeItemFromAvatar(item_to_remove);
-// }
-// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d
-// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1c) | Added: RLVa-1.2.1c
- if ( (!rlv_handler_t::isEnabled()) || (gRlvWearableLocks.canRemove(item_to_remove)) )
-// [/RLVa:KB]
- {
- const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID());
- if ( (pWearable) && (LLAssetType::AT_BODYPART != pWearable->getAssetType()) )
- {
- U32 idxWearable = gAgentWearables.getWearableIndex(pWearable);
- if (idxWearable < LLAgentWearables::MAX_CLOTHING_PER_TYPE)
- {
- gAgentWearables.removeWearable(pWearable->getType(), false, idxWearable);
-
- LLAppearanceMgr::instance().removeCOFItemLinks(item_to_remove->getLinkedUUID(), false);
- gInventory.notifyObservers();
-
-// [RLVa:KB] - Checked: 2011-06-07 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
- RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true);
-// [/RLVa:KB]
- }
- }
- }
-// [/SL:KB]
- break;
- case LLAssetType::AT_OBJECT:
- LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
- default:
- break;
- }
-
- // *HACK: Force to remove garbage from COF.
- // Unworn links or objects can't be processed by existed removing functionality
- // since it is not designed for such cases. As example attachment object can't be removed
- // since sever don't sends message _PREHASH_KillObject in that case.
- // Also we can't check is link was successfully removed from COF since in case
- // deleting attachment link removing performs asynchronously in process_kill_object callback.
- removeCOFItemLinks(id_to_remove,false);
+ LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+ removeCOFItemLinks(linked_item_id);
+ updateAppearanceFromCOF();
}
bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
@@ -3431,7 +3898,7 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
//to cause appearance of the agent to be updated
bool result = false;
- if ((result = gAgentWearables.moveWearable(item, closer_to_body)))
+ if (result = gAgentWearables.moveWearable(item, closer_to_body))
{
gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE);
}
@@ -3495,7 +3962,8 @@ LLAppearanceMgr::LLAppearanceMgr():
mAttachmentInvLinkEnabled(false),
mOutfitIsDirty(false),
mOutfitLocked(false),
- mIsInUpdateAppearanceFromCOF(false)
+ mIsInUpdateAppearanceFromCOF(false),
+ mLastUpdateRequestCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
{
LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
@@ -3583,7 +4051,7 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
if (mAttachmentInvLinkEnabled)
{
- LLAppearanceMgr::removeCOFItemLinks(item_id, false);
+ LLAppearanceMgr::removeCOFItemLinks(item_id);
}
else
{
@@ -3619,7 +4087,7 @@ void LLAppearanceMgr::onRegisterAttachmentComplete(const LLUUID& idItem)
// It may have been detached already in which case we should remove the COF link
if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isWearingAttachment(idItemBase)) )
- removeCOFItemLinks(idItemBase, false);
+ removeCOFItemLinks(idItemBase);
}
// [/SL:KB]
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 57ec94a27..2db333aa8 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -34,11 +34,13 @@
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "llviewerinventory.h"
+#include "llhttpclient.h"
class LLWearable;
class LLWearableHoldingPattern;
class LLInventoryCallback;
class LLOutfitUnLockTimer;
+class LLCallAfterInventoryLinkMgr;
class LLAppearanceMgr: public LLSingleton
{
@@ -103,6 +105,9 @@ public:
// Find the Current Outfit folder.
const LLUUID getCOF() const;
+ S32 getCOFVersion() const;
+
+ S32 mLastUpdateRequestCOFVersion;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
@@ -117,6 +122,7 @@ public:
// Update the displayed outfit name in UI.
void updatePanelOutfitName(const std::string& name);
+ void purgeBaseOutfitLink(const LLUUID& category);
void createBaseOutfitLink(const LLUUID& category, LLPointer link_waiter);
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
@@ -140,11 +146,10 @@ public:
void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer cb = NULL);
// Remove COF entries
- void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
- void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
-
- // Add COF link to ensemble folder.
- void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
+ void removeCOFItemLinks(const LLUUID& item_id);
+ void removeCOFLinksOfType(LLWearableType::EType type);
+ void removeAllClothesFromAvatar();
+ void removeAllAttachmentsFromAvatar();
//has the current outfit changed since it was loaded?
bool isOutfitDirty() { return mOutfitIsDirty; }
@@ -172,12 +177,15 @@ public:
bool updateBaseOutfit();
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
+ void removeItemsFromAvatar(const uuid_vec_t& item_ids);
void removeItemFromAvatar(const LLUUID& item_id);
-
- LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);
- LLUUID makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& item_list, bool show_panel = true);
- LLUUID makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links, bool show_panel = true);
+private:
+ LLUUID makeNewOutfitCore(const std::string& new_folder_name, bool show_panel/*=true*/, LLInventoryModel::item_array_t* items = NULL);
+public:
+ LLUUID makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel/*=true*/);
+ LLUUID makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& item_list);
+ LLUUID makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links);
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);
@@ -194,6 +202,8 @@ public:
bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
+ void requestServerAppearanceUpdate(LLHTTPClient::ResponderPtr responder_ptr = NULL);
+
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
@@ -214,14 +224,13 @@ private:
bool follow_folder_links);
void purgeCategory(const LLUUID& category, bool keep_outfit_links);
- void purgeBaseOutfitLink(const LLUUID& category);
static void onOutfitRename(const LLSD& notification, const LLSD& response);
void setOutfitLocked(bool locked);
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
- void syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLPointer cb);
+ void syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter);
// [/SL:KB]
bool mAttachmentInvLinkEnabled;
@@ -291,4 +300,5 @@ void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
// Wear all items in a uuid vector.
void wear_multiple(const uuid_vec_t& ids, bool replace);
+void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false);
#endif
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 0c47be8f2..2777da456 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -563,7 +563,6 @@ LLAppViewer::LLAppViewer() :
mSavedFinalSnapshot(false),
mQuitRequested(false),
mLogoutRequestSent(false),
- mYieldTime(-1),
mMainloopTimeout(NULL),
mAgentRegionLastAlive(false)
{
@@ -584,6 +583,15 @@ LLAppViewer::~LLAppViewer()
removeMarkerFile();
}
+class LLUITranslationBridge : public LLTranslationBridge
+{
+public:
+ virtual std::string getString(const std::string &xml_desc)
+ {
+ return LLTrans::getString(xml_desc);
+ }
+};
+
bool LLAppViewer::init()
{
//
@@ -595,6 +603,10 @@ bool LLAppViewer::init()
//
LLFastTimer::reset();
+ // initialize LLWearableType translation bridge.
+ // Memory will be cleaned up in ::cleanupClass()
+ LLWearableType::initClass(new LLUITranslationBridge());
+
//
// We can call this early.
LLFrameTimer::global_initialization();
@@ -731,7 +743,7 @@ bool LLAppViewer::init()
&gColors,
LLUIImageList::getInstance(),
ui_audio_callback,
- &LLUI::sGLScaleFactor
+ &LLUI::getScaleFactor()
);
LLWeb::initClass(); // do this after LLUI
@@ -1076,7 +1088,7 @@ bool LLAppViewer::mainLoop()
LLVoiceChannel::initClass();
LLVoiceClient::init(gServicePump);
- LLTimer frameTimer,idleTimer;
+ LLTimer frameTimer,idleTimer,periodicRenderingTimer;
LLTimer debugTime;
LLFrameTimer memCheckTimer;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
@@ -1089,6 +1101,7 @@ bool LLAppViewer::mainLoop()
// point of posting.
LLSD newFrame;
+ BOOL restore_rendering_masks = FALSE;
// Handle messages
while (!LLApp::isExiting())
@@ -1103,6 +1116,28 @@ bool LLAppViewer::mainLoop()
try
{
+ // Check if we need to restore rendering masks.
+ if (restore_rendering_masks)
+ {
+ gPipeline.popRenderDebugFeatureMask();
+ gPipeline.popRenderTypeMask();
+ }
+ // Check if we need to temporarily enable rendering.
+ static const LLCachedControl periodic_rendering("ForcePeriodicRenderingTime", 0.f);
+ if (periodic_rendering > F_APPROXIMATELY_ZERO && periodicRenderingTimer.getElapsedTimeF64() > periodic_rendering)
+ {
+ periodicRenderingTimer.reset();
+ restore_rendering_masks = TRUE;
+ gPipeline.pushRenderTypeMask();
+ gPipeline.pushRenderDebugFeatureMask();
+ gPipeline.setAllRenderTypes();
+ gPipeline.setAllRenderDebugFeatures();
+ }
+ else
+ {
+ restore_rendering_masks = FALSE;
+ }
+
pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow)
@@ -1212,7 +1247,6 @@ bool LLAppViewer::mainLoop()
pingMainloopTimeout("Main:Display");
gGLActive = TRUE;
display();
-
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
gGLActive = FALSE;
@@ -1229,12 +1263,12 @@ bool LLAppViewer::mainLoop()
LLMemType mt_sleep(LLMemType::MTYPE_SLEEP);
LLFastTimer t2(FTM_SLEEP);
static const LLCachedControl run_multiple_threads("RunMultipleThreads",false);
-
+ static const LLCachedControl yield_time("YieldTime", -1);
// yield some time to the os based on command line option
- if(mYieldTime >= 0)
+ if(yield_time >= 0)
{
LLFastTimer t(FTM_YIELD);
- ms_sleep(mYieldTime);
+ ms_sleep(yield_time);
}
// yield cooperatively when not running as foreground window
@@ -1572,6 +1606,8 @@ bool LLAppViewer::cleanup()
LLViewerObject::cleanupVOClasses();
+ LLAvatarAppearance::cleanupClass();
+
LLPostProcess::cleanupClass();
LLTracker::cleanupInstance();
@@ -1796,6 +1832,8 @@ bool LLAppViewer::cleanup()
llinfos << "File launched." << llendflush;
}
+ LLWearableType::cleanupClass();
+
LLMainLoopRepeater::instance().stop();
//release all private memory pools.
@@ -2345,8 +2383,6 @@ bool LLAppViewer::initConfiguration()
gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
}
- mYieldTime = gSavedSettings.getS32("YieldTime");
-
// XUI:translate
gSecondLife = "Singularity Viewer";
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 1b0e5614f..681cb505d 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -243,7 +243,6 @@ private:
bool mQuitRequested; // User wants to quit, may have modified documents open.
bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim.
- S32 mYieldTime;
LLSD mSettingsLocationList;
LLWatchdogTimeout* mMainloopTimeout;
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 642b0f307..77a0558f1 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -54,8 +54,8 @@
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermenufile.h"
+#include "llviewertexlayer.h"
#include "llviewerwindow.h"
-#include "lltexlayer.h"
#include "lltrans.h"
// library includes
@@ -461,7 +461,7 @@ LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
LLSendTexLayerResponder::~LLSendTexLayerResponder()
{
- // mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
+ // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below
if (mBakedUploadData)
{ // ...but delete it in the case where uploadComplete() is never called
delete mBakedUploadData;
@@ -482,12 +482,12 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
if (result == "complete"
&& mBakedUploadData != NULL)
{ // Invoke
- LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
else
{ // Invoke the original callback with an error result
- LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
}
@@ -497,7 +497,7 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
llinfos << "status: " << statusNum << " reason: " << reason << llendl;
// Invoke the original callback with an error result
- LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index 1bfd2cb9b..79ec43dfe 100644
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
@@ -2,37 +2,32 @@
* @file llcallbacklist.cpp
* @brief A simple list of callback functions to call.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llcallbacklist.h"
+#include "lleventtimer.h"
// Library includes
#include "llerror.h"
@@ -186,6 +181,54 @@ void doOnIdleRepeating(bool_func_t callable)
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
}
+class NullaryFuncEventTimer: public LLEventTimer
+{
+public:
+ NullaryFuncEventTimer(nullary_func_t callable, F32 seconds):
+ LLEventTimer(seconds),
+ mCallable(callable)
+ {
+ }
+
+private:
+ BOOL tick()
+ {
+ mCallable();
+ return TRUE;
+ }
+
+ nullary_func_t mCallable;
+};
+
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds)
+{
+ new NullaryFuncEventTimer(callable, seconds);
+}
+
+class BoolFuncEventTimer: public LLEventTimer
+{
+public:
+ BoolFuncEventTimer(bool_func_t callable, F32 seconds):
+ LLEventTimer(seconds),
+ mCallable(callable)
+ {
+ }
+private:
+ BOOL tick()
+ {
+ return mCallable();
+ }
+
+ bool_func_t mCallable;
+};
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds)
+{
+ new BoolFuncEventTimer(callable, seconds);
+}
+
#ifdef _DEBUG
void test1(void *data)
diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h
index 1819f865a..0516c9cdb 100644
--- a/indra/newview/llcallbacklist.h
+++ b/indra/newview/llcallbacklist.h
@@ -2,31 +2,25 @@
* @file llcallbacklist.h
* @brief A simple list of callback functions to call.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,7 +28,6 @@
#define LL_LLCALLBACKLIST_H
#include "llstl.h"
-#include
class LLCallbackList
{
@@ -68,6 +61,12 @@ void doOnIdleOneTime(nullary_func_t callable);
// Repeatedly call a callable in idle loop until it returns true.
void doOnIdleRepeating(bool_func_t callable);
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds);
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds);
+
extern LLCallbackList gIdleCallbacks;
#endif
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 8ea55dab0..dd260711a 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -191,18 +191,6 @@ BOOL LLFloaterScriptQueue::start()
//llinfos << "LLFloaterCompileQueue::start()" << llendl;
std::string buffer;
- LLSelectMgr *mgr = LLSelectMgr::getInstance();
- LLObjectSelectionHandle selectHandle = mgr->getSelection();
- U32 n_objects = 0;
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- n_objects = selectHandle->getObjectCount();
- }
- else
- {
- n_objects = selectHandle->getRootObjectCount();
- }
-
LLStringUtil::format_map_t args;
args["[START]"] = mStartString;
args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 616f6b58a..afe3040c4 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -2,31 +2,25 @@
* @file lldrawable.cpp
* @brief LLDrawable class implementation
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -508,7 +502,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
//scaling
LLVector3 target_scale = mVObjp->getScale();
LLVector3 old_scale = mCurrentScale;
- LLVector3 dest_scale = target_scale;
// Damping
F32 dist_squared = 0.f;
@@ -1232,7 +1225,6 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
LLCamera ret = camera;
LLXformMatrix* mat = mDrawable->getXform();
LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
- LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
LLVector3 delta = ret.getOrigin() - center;
LLQuaternion rot = ~mat->getRotation();
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index d433fe3a6..909cec540 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -2,31 +2,25 @@
* @file lldrawpool.cpp
* @brief LLDrawPool class implementation
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 890536ba2..31cd72628 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -2,31 +2,25 @@
* @file lldrawpool.h
* @brief LLDrawPool class definition
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 28a1acaab..7236c8b12 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -159,7 +159,7 @@ void LLStandardBumpmap::addstandard()
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;
LLStandardBumpmap::sStandardBumpmapCount++;
@@ -1075,7 +1075,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
src_image->getHeight() != bump->getHeight())// ||
//(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
{
- src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+ src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
src_image->forceToSaveRawImage(0) ;
}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 81a3c99ea..dc48a4e29 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -75,7 +75,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga",
- TRUE, LLViewerTexture::BOOST_UI,
+ TRUE, LLGLTexture::BOOST_UI,
LLViewerTexture::FETCHED_TEXTURE,
format, int_format,
LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
@@ -84,7 +84,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c",
- TRUE, LLViewerTexture::BOOST_UI,
+ TRUE, LLGLTexture::BOOST_UI,
LLViewerTexture::FETCHED_TEXTURE,
format, int_format,
LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
@@ -92,7 +92,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -177,7 +177,7 @@ void LLDrawPoolTerrain::render(S32 pass)
LLVLComposition *compp = regionp->getComposition();
for (S32 i = 0; i < 4; i++)
{
- compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+ compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
}
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 5c06fb1c7..2154c0495 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -74,11 +74,11 @@ LLVector3 LLDrawPoolWater::sLightDir;
LLDrawPoolWater::LLDrawPoolWater() :
LLFacePool(POOL_WATER)
{
- mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLGLTexture::BOOST_UI);
gGL.getTexUnit(0)->bind(mHBTex[0]) ;
mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLGLTexture::BOOST_UI);
gGL.getTexUnit(0)->bind(mHBTex[1]);
mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index 33287ae1a..603a73ce6 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -72,8 +72,8 @@ public:
/*virtual*/ S8 getType() const ;
- S32 getOriginX() { return mOrigin.mX; }
- S32 getOriginY() { return mOrigin.mY; }
+ S32 getOriginX() const { return mOrigin.mX; }
+ S32 getOriginY() const { return mOrigin.mY; }
S32 getSize() { return mFullWidth * mFullHeight * mComponents; }
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 277f1bb34..0092f5277 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -563,8 +563,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
/* removed in lieu of raycast uv detection
void LLFace::renderSelectedUV()
{
- LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLViewerTexture::BOOST_UI);
- LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLViewerTexture::BOOST_UI);
+ LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI);
+ LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI);
LLGLSUVSelect object_select;
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 413398cf1..a8d36867b 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -269,9 +269,6 @@ void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale)
mSection[0].mVelocity.setVec(0,0,0);
mSection[0].mAxisRotation.setQuat(begin_rot,0,0,1);
- LLVector3 parentSectionPosition = mSection[0].mPosition;
- LLVector3 last_direction = mSection[0].mDirection;
-
remapSections(mSection, mInitializedRes, mSection, mSimulateRes);
mInitializedRes = mSimulateRes;
@@ -432,6 +429,15 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
//the object is not visible
return ;
}
+
+ // stinson 11/12/2012: Need to check with davep on the following.
+ // Skipping the flexible update if render res is negative. If we were to continue with a negative value,
+ // the subsequent S32 num_render_sections = 1<getFullName(mID, mLegacyName);
- mLegacyName = LLCacheName::cleanFullName(mLegacyName);
+ if(!mNameRequested)
+ {
+ mNameRequested = true;
+ LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _2));
+ }
}
-static void on_avatar_name_lookup(const LLUUID&, const LLAvatarName& avatar_name, std::string& mDisplayName)
+void LLSpeaker::onNameCache(const LLAvatarName& avatar_name)
{
LLAvatarNameCache::getPNSName(avatar_name, mDisplayName);
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g
@@ -120,6 +118,10 @@ static void on_avatar_name_lookup(const LLUUID&, const LLAvatarName& avatar_name
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
mDisplayName = RlvStrings::getAnonym(mDisplayName);
// [/RLVa:KB]
+
+ // Also set the legacy name. We will need it to initiate a new
+ // IM session.
+ mLegacyName = LLCacheName::cleanFullName(avatar_name.getLegacyName());
}
LLSpeakerTextModerationEvent::LLSpeakerTextModerationEvent(LLSpeaker* source)
@@ -616,6 +618,7 @@ void LLPanelActiveSpeakers::refreshSpeakers()
&& selected_speakerp->mType != LLSpeaker::SPEAKER_EXTERNAL
// Ansariel: No, we don't want to mute Lindens with display names
//&& !LLMuteList::getInstance()->isLinden(selected_speakerp->mDisplayName));
+ && !selected_speakerp->mLegacyName.empty()
&& !LLMuteList::getInstance()->isLinden(selected_speakerp->mLegacyName));
}
mVolumeSlider->setValue(gVoiceClient->getUserVolume(selected_id));
@@ -788,7 +791,7 @@ void LLPanelActiveSpeakers::onDoubleClickSpeaker(void* user_data)
LLPointer speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
- if (speaker_id != gAgent.getID() && speakerp.notNull())
+ if (speaker_id != gAgent.getID() && speakerp.notNull() && !speakerp->mLegacyName.empty())
{
// Changed for display name support
//gIMMgr->addSession(speakerp->mDisplayName, IM_NOTHING_SPECIAL, speaker_id);
diff --git a/indra/newview/llfloateractivespeakers.h b/indra/newview/llfloateractivespeakers.h
index 757c00bc7..efad321cb 100644
--- a/indra/newview/llfloateractivespeakers.h
+++ b/indra/newview/llfloateractivespeakers.h
@@ -39,7 +39,9 @@
#include "llvoiceclient.h"
#include "llframetimer.h"
#include "llevent.h"
+
#include
+#include
class LLScrollListCtrl;
class LLButton;
@@ -52,7 +54,7 @@ class LLCheckBoxCtrl;
// data for a given participant in a voice channel
-class LLSpeaker : public LLRefCount, public LLOldEvents::LLObservable, public LLHandleProvider
+class LLSpeaker : public LLRefCount, public LLOldEvents::LLObservable, public LLHandleProvider, public boost::signals2::trackable
{
public:
typedef enum e_speaker_type
@@ -76,6 +78,7 @@ public:
LLSpeaker(const LLUUID& id, const std::string& name = LLStringUtil::null, const ESpeakerType type = SPEAKER_AGENT);
~LLSpeaker() {};
void lookupName();
+ void onNameCache(const LLAvatarName& avatar_name);
ESpeakerStatus mStatus; // current activity status in speech group
F32 mLastSpokeTime; // timestamp when this speaker last spoke
@@ -92,6 +95,7 @@ public:
BOOL mModeratorMutedVoice;
BOOL mModeratorMutedText;
std::string mLegacyName;
+ bool mNameRequested;
};
class LLSpeakerTextModerationEvent : public LLOldEvents::LLEvent
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 52eee0eb8..6aa573ba8 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -1547,12 +1547,12 @@ BOOL LLPreviewAnimation::render()
gGL.flush();
- LLVector3 target_pos = avatarp->mRoot.getWorldPosition();
+ LLVector3 target_pos = avatarp->mRoot->getWorldPosition();
LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
LLQuaternion(mCameraYaw, LLVector3::z_axis);
- LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot;
+ LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
LLViewerCamera::getInstance()->setOriginAndLookAt(
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
LLVector3::z_axis, // up
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 70f79f3c5..4e6312175 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -40,7 +40,7 @@
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLUUID& id) :
LLFloater(std::string("avatar_texture_debug")),
@@ -72,7 +72,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
{
for (U32 i=0; i < TEX_NUM_INDICES; i++)
{
- const std::string tex_name = LLVOAvatarDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
+ const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
mTextures[i] = getChild(tex_name);
}
mTitle = getTitle();
diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h
index 4138edeb4..82bf95423 100644
--- a/indra/newview/llfloateravatartextures.h
+++ b/indra/newview/llfloateravatartextures.h
@@ -36,7 +36,7 @@
#include "llfloater.h"
#include "lluuid.h"
#include "llstring.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
class LLTextureCtrl;
@@ -59,7 +59,7 @@ private:
private:
LLUUID mID;
std::string mTitle;
- LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+ LLTextureCtrl* mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
};
#endif
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index 66a417dda..0bde0cfee 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -54,6 +54,7 @@
#include "llviewerregion.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
+#include "llinventoryicon.h"
#include "hippogridmanager.h"
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 2c1631987..02468dd65 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -512,7 +512,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
LLTextBox* resellable_clause = getChild("resellable_clause");
if (resellable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
{
resellable_clause->setText(getString("can_not_resell"));
}
@@ -525,7 +525,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
LLTextBox* changeable_clause = getChild("changeable_clause");
if (changeable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
{
changeable_clause->setText(getString("can_change"));
}
diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp
index 680df5f05..f46daa693 100644
--- a/indra/newview/llfloatercustomize.cpp
+++ b/indra/newview/llfloatercustomize.cpp
@@ -50,7 +50,6 @@
#include "llscrollcontainer.h"
#include "llscrollingpanelparam.h"
#include "llsliderctrl.h"
-#include "lltabcontainervertical.h"
#include "llviewerwindow.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
@@ -78,16 +77,14 @@
#include "llnotificationsutil.h"
#include "llpaneleditwearable.h"
#include "llmakeoutfitdialog.h"
+#include "llagentcamera.h"
#include "statemachine/aifilepicker.h"
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
// *TODO:translate : The ui xml for this really needs to be integrated with the appearance paramaters
-// Globals
-LLFloaterCustomize* gFloaterCustomize = NULL;
-
/////////////////////////////////////////////////////////////////////
// LLFloaterCustomizeObserver
@@ -121,22 +118,19 @@ BOOL edit_wearable_for_teens(LLWearableType::EType type)
void updateAvatarHeightDisplay()
{
- if (gFloaterCustomize && isAgentAvatarValid())
+ if (LLFloaterCustomize::instanceExists() && isAgentAvatarValid())
{
F32 avatar_size = (gAgentAvatarp->mBodySize.mV[VZ]) + (F32)0.17; //mBodySize is actually quite a bit off.
- gFloaterCustomize->getChild("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m");
+ LLFloaterCustomize::getInstance()->getChild("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m");
F32 feet = avatar_size / 0.3048;
F32 inches = (feet - (F32)((U32)feet)) * 12.0;
- gFloaterCustomize->getChild("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches));
+ LLFloaterCustomize::getInstance()->getChild("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches));
}
}
/////////////////////////////////////////////////////////////////////
// LLFloaterCustomize
-// statics
-LLWearableType::EType LLFloaterCustomize::sCurrentWearableType = LLWearableType::WT_INVALID;
-
struct WearablePanelData
{
WearablePanelData(LLFloaterCustomize* floater, LLWearableType::EType type)
@@ -148,7 +142,8 @@ struct WearablePanelData
LLFloaterCustomize::LLFloaterCustomize()
: LLFloater(std::string("customize")),
mScrollingPanelList( NULL ),
- mInventoryObserver(NULL)
+ mInventoryObserver(NULL),
+ mCurrentWearableType(LLWearableType::WT_INVALID)
{
memset(&mWearablePanelList[0],0,sizeof(char*)*LLWearableType::WT_COUNT); //Initialize to 0
@@ -173,8 +168,23 @@ LLFloaterCustomize::LLFloaterCustomize()
}
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map);
+
+ fetchInventory(); //May as well start requesting now.
+
+ LLFloater::open();
+
+ setVisible(false);
}
+LLFloaterCustomize::~LLFloaterCustomize()
+{
+ llinfos << "Destroying LLFloaterCustomize" << llendl;
+ mResetParams = NULL;
+ gInventory.removeObserver(mInventoryObserver);
+ delete mInventoryObserver;
+}
+
+// virtual
BOOL LLFloaterCustomize::postBuild()
{
getChild("Make Outfit")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnMakeOutfit, this));
@@ -185,14 +195,11 @@ BOOL LLFloaterCustomize::postBuild()
getChild("Import")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnImport, this));
getChild("Export")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnExport, this));
- // Wearable panels
- initWearablePanels();
-
// Tab container
LLTabContainer* tab_container = getChild("customize tab container");
if(tab_container)
{
- tab_container->setCommitCallback(boost::bind(&LLFloaterCustomize::onTabChanged, _2));
+ tab_container->setCommitCallback(boost::bind(&LLFloaterCustomize::onTabChanged, this, _2));
tab_container->setValidateCallback(boost::bind(&LLFloaterCustomize::onTabPrecommit, this, _1, _2));
}
@@ -214,31 +221,71 @@ BOOL LLFloaterCustomize::postBuild()
return TRUE;
}
-void LLFloaterCustomize::open()
+//static
+void LLFloaterCustomize::editWearable(LLViewerWearable* wearable, bool disable_camera_switch)
{
- LLFloater::open();
- // childShowTab depends on gFloaterCustomize being defined and therefore must be called after the constructor. - Nyx
- childShowTab("customize tab container", "Shape", true);
- setCurrentWearableType(LLWearableType::WT_SHAPE);
+ if(!wearable)
+ return;
+ LLFloaterCustomize::getInstance()->setCurrentWearableType(wearable->getType(), disable_camera_switch);
+}
+
+//static
+void LLFloaterCustomize::show()
+{
+ if(!LLFloaterCustomize::instanceExists())
+ {
+ const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(LLWearableType::WT_SHAPE);
+ LLFloaterCustomize::getInstance()->setCurrentWearableType(LLWearableType::WT_SHAPE, disable_camera_switch);
+ }
+ else
+ LLFloaterCustomize::getInstance()->setFrontmost(true);
+}
+
+// virtual
+void LLFloaterCustomize::onClose(bool app_quitting)
+{
+ // since this window is potentially staying open, push to back to let next window take focus
+ gFloaterView->sendChildToBack(this);
+ // askToSaveIfDirty will call delayedClose immediately if there's nothing to save.
+ askToSaveIfDirty( boost::bind(&LLFloaterCustomize::delayedClose, this, _1, app_quitting) );
+}
+
+void LLFloaterCustomize::delayedClose(bool proceed, bool app_quitting)
+{
+ if(proceed)
+ {
+ LLVOAvatarSelf::onCustomizeEnd();
+ LLFloater::onClose(app_quitting);
+ }
}
////////////////////////////////////////////////////////////////////////////
-// static
-void LLFloaterCustomize::setCurrentWearableType( LLWearableType::EType type )
+void LLFloaterCustomize::setCurrentWearableType( LLWearableType::EType type, bool disable_camera_switch )
{
- if( LLFloaterCustomize::sCurrentWearableType != type )
+ if( mCurrentWearableType != type )
{
- LLFloaterCustomize::sCurrentWearableType = type;
+ mCurrentWearableType = type;
+
+ if (!gAgentCamera.cameraCustomizeAvatar())
+ {
+ LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
+ }
+ else if(!gSavedSettings.getBOOL("AppearanceCameraMovement") || disable_camera_switch) //Break out to free camera.
+ {
+ gAgentCamera.changeCameraToDefault();
+ gAgentCamera.resetView();
+ }
S32 type_int = (S32)type;
- if( gFloaterCustomize
- && gFloaterCustomize->mWearablePanelList[type_int])
+ if(mWearablePanelList[type_int])
{
- std::string panelname = gFloaterCustomize->mWearablePanelList[type_int]->getName();
- gFloaterCustomize->childShowTab("customize tab container", panelname);
- gFloaterCustomize->switchToDefaultSubpart();
+ std::string panelname = mWearablePanelList[type_int]->getName();
+ childShowTab("customize tab container", panelname);
+ switchToDefaultSubpart();
}
+
+ updateVisiblity(disable_camera_switch);
}
}
@@ -328,7 +375,7 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker)
for( S32 i=0; i < LLWearableType::WT_COUNT; i++ )
{
is_modifiable = FALSE;
- LLWearable* old_wearable = gAgentWearables.getWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE
+ LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE
if( old_wearable )
{
item = gInventory.getItem(old_wearable->getItemID());
@@ -352,7 +399,7 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker)
for( S32 i=0; i < LLWearableType::WT_COUNT; i++ )
{
is_modifiable = FALSE;
- LLWearable* old_wearable = gAgentWearables.getWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE
+ LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE
if( old_wearable )
{
item = gInventory.getItem(old_wearable->getItemID());
@@ -390,7 +437,7 @@ void LLFloaterCustomize::onBtnOk()
}
gFloaterView->sendChildToBack(this);
- handle_reset_view(); // Calls askToSaveIfDirty
+ close(false);
}
void LLFloaterCustomize::onBtnMakeOutfit()
@@ -405,34 +452,17 @@ void* LLFloaterCustomize::createWearablePanel(void* userdata)
{
WearablePanelData* data = (WearablePanelData*)userdata;
LLWearableType::EType type = data->mType;
- LLPanelEditWearable* panel;
- if ((gAgent.isTeen() && !edit_wearable_for_teens(data->mType) ))
- {
- panel = NULL;
- }
+ LLPanelEditWearable* &panel = data->mFloater->mWearablePanelList[type];
+ if (!gAgent.isTeen() || edit_wearable_for_teens(type))
+ panel = new LLPanelEditWearable( type, data->mFloater );
else
- {
- panel = new LLPanelEditWearable( type );
- }
- data->mFloater->mWearablePanelList[type] = panel;
+ panel = NULL;
delete data;
return panel;
}
-void LLFloaterCustomize::initWearablePanels()
-{
-}
-
////////////////////////////////////////////////////////////////////////////
-LLFloaterCustomize::~LLFloaterCustomize()
-{
- llinfos << "Destroying LLFloaterCustomize" << llendl;
- mResetParams = NULL;
- gInventory.removeObserver(mInventoryObserver);
- delete mInventoryObserver;
-}
-
void LLFloaterCustomize::switchToDefaultSubpart()
{
getCurrentWearablePanel()->showDefaultSubpart();
@@ -460,12 +490,12 @@ void LLFloaterCustomize::draw()
LLFloater::draw();
}
-BOOL LLFloaterCustomize::isDirty() const
+bool LLFloaterCustomize::isWearableDirty() const
{
LLWearableType::EType cur = getCurrentWearableType();
for(U32 i = 0; i < gAgentWearables.getWearableCount(cur); ++i)
{
- LLWearable* wearable = gAgentWearables.getWearable(cur,i);
+ LLViewerWearable* wearable = gAgentWearables.getViewerWearable(cur,i);
if(wearable && wearable->isDirty())
return TRUE;
}
@@ -482,9 +512,9 @@ bool LLFloaterCustomize::onTabPrecommit( LLUICtrl* ctrl, const LLSD& param )
if(type_name == panel_name)
{
- if(LLFloaterCustomize::sCurrentWearableType != type)
+ if(mCurrentWearableType != type)
{
- askToSaveIfDirty(boost::bind(&LLFloaterCustomize::onCommitChangeTab, _1, (LLTabContainer*)ctrl, param.asString(), (LLWearableType::EType)type));
+ askToSaveIfDirty(boost::bind(&LLFloaterCustomize::onCommitChangeTab, this, _1, (LLTabContainer*)ctrl, param.asString(), (LLWearableType::EType)type));
return false;
}
}
@@ -493,7 +523,6 @@ bool LLFloaterCustomize::onTabPrecommit( LLUICtrl* ctrl, const LLSD& param )
}
-// static
void LLFloaterCustomize::onTabChanged( const LLSD& param )
{
std::string panel_name = param.asString();
@@ -504,28 +533,22 @@ void LLFloaterCustomize::onTabChanged( const LLSD& param )
if(type_name == panel_name)
{
- LLFloaterCustomize::setCurrentWearableType((LLWearableType::EType)type);
+ const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch((LLWearableType::EType)type);
+ setCurrentWearableType((LLWearableType::EType)type, disable_camera_switch);
break;
}
}
}
-void LLFloaterCustomize::onClose(bool app_quitting)
-{
- // since this window is potentially staying open, push to back to let next window take focus
- gFloaterView->sendChildToBack(this);
- handle_reset_view(); // Calls askToSaveIfDirty
-}
-
-// static
void LLFloaterCustomize::onCommitChangeTab(BOOL proceed, LLTabContainer* ctrl, std::string panel_name, LLWearableType::EType type)
{
- if (!proceed || !gFloaterCustomize)
+ if (!proceed)
{
return;
}
- LLFloaterCustomize::setCurrentWearableType(type);
+ const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(type);
+ setCurrentWearableType(type, disable_camera_switch);
ctrl->selectTabByName(panel_name);
}
@@ -567,6 +590,15 @@ void LLFloaterCustomize::wearablesChanged(LLWearableType::EType type)
}
}
+void LLFloaterCustomize::updateVisiblity(bool force_disable_camera_switch/*=false*/)
+{
+ if(!getVisible())
+ {
+ if(force_disable_camera_switch || !gAgentCamera.cameraCustomizeAvatar() || !gAgentCamera.getCameraAnimating() || (gMorphView && gMorphView->getVisible()))
+ setVisibleAndFrontmost(TRUE);
+ }
+}
+
void LLFloaterCustomize::updateScrollingPanelList()
{
getCurrentWearablePanel()->updateScrollingPanelList();
@@ -574,7 +606,7 @@ void LLFloaterCustomize::updateScrollingPanelList()
void LLFloaterCustomize::askToSaveIfDirty( boost::function cb )
{
- if(isDirty())
+ if(isWearableDirty())
{
// Ask if user wants to save, then continue to next step afterwards
mNextStepAfterSaveCallback.connect(cb);
@@ -599,7 +631,7 @@ bool LLFloaterCustomize::onSaveDialog(const LLSD& notification, const LLSD& resp
for(U32 i = 0;i < gAgentWearables.getWearableCount(cur);++i)
{
- LLWearable* wearable = gAgentWearables.getWearable(cur,i);
+ LLViewerWearable* wearable = gAgentWearables.getViewerWearable(cur,i);
if(wearable && wearable->isDirty())
{
switch( option )
@@ -678,7 +710,7 @@ void LLFloaterCustomize::updateInventoryUI()
panel = mWearablePanelList[i];
if(panel)
{
- LLWearable* wearable = panel->getWearable();
+ LLViewerWearable* wearable = panel->getWearable();
if(wearable)
item = gInventory.getItem(wearable->getItemID());
}
@@ -696,7 +728,7 @@ void LLFloaterCustomize::updateInventoryUI()
is_complete = false;
perm_mask = 0x0;
}
- if(i == sCurrentWearableType)
+ if(i == mCurrentWearableType)
{
if(panel)
{
diff --git a/indra/newview/llfloatercustomize.h b/indra/newview/llfloatercustomize.h
index d82d7c267..56047db1e 100644
--- a/indra/newview/llfloatercustomize.h
+++ b/indra/newview/llfloatercustomize.h
@@ -43,6 +43,7 @@
#include "llviewermenu.h"
#include "llwearable.h"
#include "lliconctrl.h"
+#include "llsingleton.h"
class LLButton;
class LLIconCtrl;
@@ -62,6 +63,7 @@ class LLViewerJointMesh;
class LLViewerVisualParam;
class LLVisualParam;
class LLVisualParamReset;
+class LLViewerWearable;
class LLWearableSaveAsDialog;
class LLPanelEditWearable;
class AIFilePicker;
@@ -69,74 +71,82 @@ class AIFilePicker;
/////////////////////////////////////////////////////////////////////
// LLFloaterCustomize
-class LLFloaterCustomize : public LLFloater
+class LLFloaterCustomize : public LLFloater, public LLSingleton
{
public:
+ // Ctor/Dtor
LLFloaterCustomize();
virtual ~LLFloaterCustomize();
- virtual BOOL postBuild();
- // Inherted methods from LLFloater (and above)
- virtual void onClose(bool app_quitting);
- virtual void draw();
- /*virtual*/ void open();
+ // Inherted methods
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void draw();
+
+ // Creation procedures
+ static void editWearable(LLViewerWearable* wearable, bool disable_camera_switch);
+ static void show();
- // New methods
+private:
+ // Initilization
+ void initWearablePanels();
+ void initScrollingPanelList();
+ // Deinitilization
+ void delayedClose(bool proceed, bool app_quitting);
+
+ // Setters/Getters
+ void setCurrentWearableType(LLWearableType::EType type, bool disable_camera_switch);
+public:
+ LLWearableType::EType getCurrentWearableType() const { return mCurrentWearableType; }
+ LLPanelEditWearable* getCurrentWearablePanel() const { return mWearablePanelList[ mCurrentWearableType ]; }
+ LLScrollingPanelList* getScrollingPanelList() const { return mScrollingPanelList; } //LLPanelEditWearable needs access to this.
+
+ // Updates
void wearablesChanged(LLWearableType::EType type);
+public:
void updateScrollingPanelList();
- LLPanelEditWearable* getCurrentWearablePanel() { return mWearablePanelList[ sCurrentWearableType ]; }
+ void updateVisiblity(bool force_disable_camera_switch = false);
+private:
+ void updateInventoryUI();
- virtual BOOL isDirty() const;
+ // Utility
+ void fetchInventory();
+ bool isWearableDirty() const;
+public:
void askToSaveIfDirty( boost::function cb );
-
void switchToDefaultSubpart();
- static void setCurrentWearableType( LLWearableType::EType type );
- static LLWearableType::EType getCurrentWearableType() { return sCurrentWearableType; }
-
+private:
// Callbacks
void onBtnOk();
void onBtnMakeOutfit();
- void onMakeOutfitCommit();
void onBtnImport();
static void onBtnImport_continued(AIFilePicker* filepicker);
void onBtnExport();
static void onBtnExport_continued(AIFilePicker* filepicker);
-
- static void onTabChanged( const LLSD& param );
+ void onTabChanged( const LLSD& param );
bool onTabPrecommit( LLUICtrl* ctrl, const LLSD& param );
bool onSaveDialog(const LLSD& notification, const LLSD& response);
- static void onCommitChangeTab(BOOL proceed, LLTabContainer* ctrl, std::string panel_name, LLWearableType::EType type);
+ void onCommitChangeTab(BOOL proceed, LLTabContainer* ctrl, std::string panel_name, LLWearableType::EType type);
+
+ // LLCallbackMap callback.
+ static void* createWearablePanel(void* userdata);
- void fetchInventory();
- void updateInventoryUI();
+ // Member variables
+ LLPanelEditWearable* mWearablePanelList[ LLWearableType::WT_COUNT ];
- LLScrollingPanelList* getScrollingPanelList() const { return mScrollingPanelList; }
-protected:
- LLPanelEditWearable* mWearablePanelList[ LLWearableType::WT_COUNT ];
+ LLWearableType::EType mCurrentWearableType;
- static LLWearableType::EType sCurrentWearableType;
+ LLScrollingPanelList* mScrollingPanelList;
+ LLScrollableContainerView* mScrollContainer;
+ LLPointer mResetParams;
- LLScrollingPanelList* mScrollingPanelList;
- LLScrollableContainerView* mScrollContainer;
- LLPointer mResetParams;
-
- LLInventoryObserver* mInventoryObserver;
+ LLInventoryObserver* mInventoryObserver;
boost::signals2::signal mNextStepAfterSaveCallback;
-
-protected:
-
- static void* createWearablePanel(void* userdata);
-
- void initWearablePanels();
- void initScrollingPanelList();
};
-extern LLFloaterCustomize* gFloaterCustomize;
-
-
#endif // LL_LLFLOATERCUSTOMIZE_H
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index e51e84af0..4ab128f1b 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -2,31 +2,25 @@
* @file llfloatergodtools.cpp
* @brief The on-screen rectangle with tool options.
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,6 +28,7 @@
#include "llfloatergodtools.h"
+#include "llavatarnamecache.h"
#include "llcoord.h"
#include "llfontgl.h"
#include "llframetimer.h"
@@ -46,7 +41,6 @@
#include "llagent.h"
#include "llalertdialog.h"
-#include "llavatarnamecache.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@@ -84,30 +78,33 @@
const F32 SECONDS_BETWEEN_UPDATE_REQUESTS = 5.0f;
-static LLFloaterGodTools* sGodTools = NULL;
-
// *****************************************************************************
// LLFloaterGodTools
// *****************************************************************************
-// static
-LLFloaterGodTools* LLFloaterGodTools::instance()
+void LLFloaterGodTools::onOpen()
{
- if (!sGodTools)
+ center();
+ setFocus(TRUE);
+// LLPanel *panel = getChild("GodTools Tabs")->getCurrentPanel();
+// if (panel)
+// panel->setFocus(TRUE);
+ LLPanel *panel = childGetVisibleTab("GodTools Tabs");
+ if (panel) panel->setFocus(TRUE);
+ if (mPanelObjectTools)
+ mPanelObjectTools->setTargetAvatar(LLUUID::null);
+
+ if (gAgent.getRegionHost() != mCurrentHost)
{
- sGodTools = new LLFloaterGodTools();
- sGodTools->open(); /*Flawfinder: ignore*/
- sGodTools->center();
- sGodTools->setFocus(TRUE);
+ // we're in a new region
+ sendRegionInfoRequest();
}
- return sGodTools;
}
-
// static
void LLFloaterGodTools::refreshAll()
{
- LLFloaterGodTools* god_tools = instance();
+ LLFloaterGodTools* god_tools = instanceExists() ? getInstance() : NULL;
if (god_tools)
{
if (gAgent.getRegionHost() != god_tools->mCurrentHost)
@@ -131,14 +128,17 @@ LLFloaterGodTools::LLFloaterGodTools()
factory_map["objects"] = LLCallbackMap(createPanelObjects, this);
factory_map["request"] = LLCallbackMap(createPanelRequest, this);
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml", &factory_map);
+}
+BOOL LLFloaterGodTools::postBuild()
+{
getChild("GodTools Tabs")->setCommitCallback(boost::bind(&LLFloaterGodTools::onTabChanged,_1,_2));
sendRegionInfoRequest();
-
- childShowTab("GodTools Tabs", "region");
+ getChild("GodTools Tabs")->selectTabByName("region");
childSetTextArg("land cost text", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
+ return TRUE;
}
// static
@@ -175,9 +175,9 @@ LLFloaterGodTools::~LLFloaterGodTools()
}
-U32 LLFloaterGodTools::computeRegionFlags() const
+U64 LLFloaterGodTools::computeRegionFlags() const
{
- U32 flags = gAgent.getRegion()->getRegionFlags();
+ U64 flags = gAgent.getRegion()->getRegionFlags();
if (mPanelRegionTools) flags = mPanelRegionTools->computeRegionFlags(flags);
if (mPanelObjectTools) flags = mPanelObjectTools->computeRegionFlags(flags);
return flags;
@@ -188,15 +188,6 @@ void LLFloaterGodTools::updatePopup(LLCoordGL center, MASK mask)
{
}
-// virtual
-void LLFloaterGodTools::onClose(bool app_quitting)
-{
- if (sGodTools)
- {
- sGodTools->setVisible(FALSE);
- }
-}
-
// virtual
void LLFloaterGodTools::draw()
{
@@ -217,31 +208,23 @@ void LLFloaterGodTools::draw()
// static
void LLFloaterGodTools::show(void *)
{
- LLFloaterGodTools* god_tools = instance();
- god_tools->open();
- LLPanel *panel = god_tools->childGetVisibleTab("GodTools Tabs");
- if (panel) panel->setFocus(TRUE);
- if (god_tools->mPanelObjectTools) god_tools->mPanelObjectTools->setTargetAvatar(LLUUID::null);
-
- if (gAgent.getRegionHost() != god_tools->mCurrentHost)
- {
- // we're in a new region
- god_tools->sendRegionInfoRequest();
- }
+ getInstance()->open();
}
-void LLFloaterGodTools::hide(void *)
+// static
+void LLFloaterGodTools::hide()
{
- if(sGodTools)
- sGodTools->setVisible(FALSE);;
+ if(instanceExists())
+ getInstance()->close();
}
void LLFloaterGodTools::showPanel(const std::string& panel_name)
{
- childShowTab("GodTools Tabs", panel_name);
+ getChild("GodTools Tabs")->selectTabByName(panel_name);
open(); /*Flawfinder: ignore*/
- LLPanel *panel = childGetVisibleTab("GodTools Tabs");
- if (panel) panel->setFocus(TRUE);
+ LLPanel *panel = getChild("GodTools Tabs")->getCurrentPanel();
+ if (panel)
+ panel->setFocus(TRUE);
}
//static
@@ -259,7 +242,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
if (!msg) return;
//const S32 SIM_NAME_BUF = 256;
- U32 region_flags;
+ U64 region_flags;
U8 sim_access;
U8 agent_limit;
std::string sim_name;
@@ -280,13 +263,23 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id);
msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id);
- msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, region_flags);
msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, sim_access);
msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, agent_limit);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
+ if (msg->has(_PREHASH_RegionInfo3))
+ {
+ msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, region_flags);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+ region_flags = flags;
+ }
+
if (host != gAgent.getRegionHost())
{
// Update is for a different region than the one we're in.
@@ -312,15 +305,16 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
regionp->setBillableFactor(billable_factor);
}
- if (!sGodTools) return;
+ LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL;
+ if (!god_tools) return;
// push values to god tools, if available
if ( gAgent.isGodlike()
- && sGodTools->mPanelRegionTools
- && sGodTools->mPanelObjectTools)
+ && god_tools->mPanelRegionTools
+ && god_tools->mPanelObjectTools)
{
- LLPanelRegionTools* rtool = sGodTools->mPanelRegionTools;
- sGodTools->mCurrentHost = host;
+ LLPanelRegionTools* rtool = god_tools->mPanelRegionTools;
+ god_tools->mCurrentHost = host;
// store locally
rtool->setSimName(sim_name);
@@ -333,7 +327,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
rtool->setRedirectGridY(redirect_grid_y);
rtool->enableAllWidgets();
- LLPanelObjectTools *otool = sGodTools->mPanelObjectTools;
+ LLPanelObjectTools *otool = god_tools->mPanelObjectTools;
otool->setCheckFlags(region_flags);
otool->enableAllWidgets();
@@ -376,17 +370,19 @@ void LLFloaterGodTools::sendRegionInfoRequest()
void LLFloaterGodTools::sendGodUpdateRegionInfo()
{
- if (!sGodTools) return;
+ LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL;
+ if (!god_tools) return;
LLViewerRegion *regionp = gAgent.getRegion();
if (gAgent.isGodlike()
- && sGodTools->mPanelRegionTools
+ && god_tools->mPanelRegionTools
&& regionp
&& gAgent.getRegionHost() == mCurrentHost)
{
LLMessageSystem *msg = gMessageSystem;
- LLPanelRegionTools *rtool = sGodTools->mPanelRegionTools;
+ LLPanelRegionTools *rtool = god_tools->mPanelRegionTools;
+ U64 region_flags = computeRegionFlags();
msg->newMessage("GodUpdateRegionInfo");
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -395,11 +391,14 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
msg->addStringFast(_PREHASH_SimName, rtool->getSimName());
msg->addU32Fast(_PREHASH_EstateID, rtool->getEstateID());
msg->addU32Fast(_PREHASH_ParentEstateID, rtool->getParentEstateID());
- msg->addU32Fast(_PREHASH_RegionFlags, computeRegionFlags());
+ // Legacy flags
+ msg->addU32Fast(_PREHASH_RegionFlags, U32(region_flags));
msg->addF32Fast(_PREHASH_BillableFactor, rtool->getBillableFactor());
msg->addS32Fast(_PREHASH_PricePerMeter, rtool->getPricePerMeter());
msg->addS32Fast(_PREHASH_RedirectGridX, rtool->getRedirectGridX());
msg->addS32Fast(_PREHASH_RedirectGridY, rtool->getRedirectGridY());
+ msg->nextBlockFast(_PREHASH_RegionInfo2);
+ msg->addU64Fast(_PREHASH_RegionFlagsExtended, region_flags);
gAgent.sendReliableMessage();
}
@@ -449,54 +448,54 @@ LLPanelRegionTools::LLPanelRegionTools(const std::string& title)
BOOL LLPanelRegionTools::postBuild()
{
- childSetCommitCallback("region name", onChangeAnything, this);
+ getChild("region name")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetKeystrokeCallback("region name", onChangeSimName, this);
childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe);
- childSetCommitCallback("check prelude", onChangePrelude, this);
- childSetCommitCallback("check fixed sun", onChangeAnything, this);
- childSetCommitCallback("check reset home", onChangeAnything, this);
- childSetCommitCallback("check visible", onChangeAnything, this);
- childSetCommitCallback("check damage", onChangeAnything, this);
- childSetCommitCallback("block dwell", onChangeAnything, this);
- childSetCommitCallback("block terraform", onChangeAnything, this);
- childSetCommitCallback("allow transfer", onChangeAnything, this);
- childSetCommitCallback("is sandbox", onChangeAnything, this);
+ getChild("check prelude")->setCommitCallback(boost::bind(&LLPanelRegionTools:: onChangePrelude, this));
+ getChild("check fixed sun")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("check reset home")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("check visible")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("check damage")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("block dwell")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("block terraform")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("allow transfer")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ getChild("is sandbox")->setCommitCallback( boost::bind(&LLPanelRegionTools::onChangeAnything, this));
- childSetAction("Bake Terrain", onBakeTerrain, this);
- childSetAction("Revert Terrain", onRevertTerrain, this);
- childSetAction("Swap Terrain", onSwapTerrain, this);
+ childSetAction("Bake Terrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this));
+ childSetAction("Revert Terrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this));
+ childSetAction("Swap Terrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this));
- childSetCommitCallback("estate", onChangeAnything, this);
+ getChild("estate")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32);
- childSetCommitCallback("parentestate", onChangeAnything, this);
+ getChild("parentestate")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32);
childDisable("parentestate");
- childSetCommitCallback("gridposx", onChangeAnything, this);
+ getChild("gridposx")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetPrevalidate("gridposx", &LLLineEditor::prevalidatePositiveS32);
childDisable("gridposx");
- childSetCommitCallback("gridposy", onChangeAnything, this);
+ getChild("gridposy")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetPrevalidate("gridposy", &LLLineEditor::prevalidatePositiveS32);
childDisable("gridposy");
- childSetCommitCallback("redirectx", onChangeAnything, this);
+ getChild("redirectx")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetPrevalidate("redirectx", &LLLineEditor::prevalidatePositiveS32);
- childSetCommitCallback("redirecty", onChangeAnything, this);
+ getChild("redirecty")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
childSetPrevalidate("redirecty", &LLLineEditor::prevalidatePositiveS32);
- childSetCommitCallback("billable factor", onChangeAnything, this);
+ getChild("billable factor")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
- childSetCommitCallback("land cost", onChangeAnything, this);
+ getChild("land cost")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
- childSetAction("Refresh", onRefresh, this);
- childSetAction("Apply", onApplyChanges, this);
+ childSetAction("Refresh", boost::bind(&LLPanelRegionTools::onRefresh, this));
+ childSetAction("Apply", boost::bind(&LLPanelRegionTools::onApplyChanges, this));
- childSetAction("Select Region", onSelectRegion, this);
- childSetAction("Autosave now", onSaveState, this);
+ childSetAction("Select Region", boost::bind(&LLPanelRegionTools::onSelectRegion, this));
+ childSetAction("Autosave now", boost::bind(onSaveState, this));
return TRUE;
}
@@ -507,7 +506,7 @@ LLPanelRegionTools::~LLPanelRegionTools()
// base class will take care of everything
}
-U32 LLPanelRegionTools::computeRegionFlags(U32 flags) const
+U64 LLPanelRegionTools::computeRegionFlags(U64 flags) const
{
flags &= getRegionFlagsMask();
flags |= getRegionFlags();
@@ -523,42 +522,42 @@ void LLPanelRegionTools::refresh()
void LLPanelRegionTools::clearAllWidgets()
{
// clear all widgets
- childSetValue("region name", "unknown");
- childSetFocus("region name", FALSE);
+ getChild("region name")->setValue("unknown");
+ getChild("region name")->setFocus( FALSE);
- childSetValue("check prelude", FALSE);
- childDisable("check prelude");
+ getChild("check prelude")->setValue(FALSE);
+ getChildView("check prelude")->setEnabled(FALSE);
- childSetValue("check fixed sun", FALSE);
- childDisable("check fixed sun");
+ getChild("check fixed sun")->setValue(FALSE);
+ getChildView("check fixed sun")->setEnabled(FALSE);
- childSetValue("check reset home", FALSE);
- childDisable("check reset home");
+ getChild("check reset home")->setValue(FALSE);
+ getChildView("check reset home")->setEnabled(FALSE);
- childSetValue("check damage", FALSE);
- childDisable("check damage");
+ getChild("check damage")->setValue(FALSE);
+ getChildView("check damage")->setEnabled(FALSE);
- childSetValue("check visible", FALSE);
- childDisable("check visible");
+ getChild("check visible")->setValue(FALSE);
+ getChildView("check visible")->setEnabled(FALSE);
- childSetValue("block terraform", FALSE);
- childDisable("block terraform");
+ getChild("block terraform")->setValue(FALSE);
+ getChildView("block terraform")->setEnabled(FALSE);
- childSetValue("block dwell", FALSE);
- childDisable("block dwell");
+ getChild("block dwell")->setValue(FALSE);
+ getChildView("block dwell")->setEnabled(FALSE);
- childSetValue("is sandbox", FALSE);
- childDisable("is sandbox");
+ getChild("is sandbox")->setValue(FALSE);
+ getChildView("is sandbox")->setEnabled(FALSE);
- childSetValue("billable factor", BILLABLE_FACTOR_DEFAULT);
- childDisable("billable factor");
+ getChild("billable factor")->setValue(BILLABLE_FACTOR_DEFAULT);
+ getChildView("billable factor")->setEnabled(FALSE);
- childSetValue("land cost", PRICE_PER_METER_DEFAULT);
- childDisable("land cost");
+ getChild("land cost")->setValue(PRICE_PER_METER_DEFAULT);
+ getChildView("land cost")->setEnabled(FALSE);
- childDisable("Apply");
- childDisable("Bake Terrain");
- childDisable("Autosave now");
+ getChildView("Apply")->setEnabled(FALSE);
+ getChildView("Bake Terrain")->setEnabled(FALSE);
+ getChildView("Autosave now")->setEnabled(FALSE);
}
@@ -566,25 +565,23 @@ void LLPanelRegionTools::enableAllWidgets()
{
// enable all of the widgets
- childEnable("check prelude");
- childEnable("check fixed sun");
- childEnable("check reset home");
- childEnable("check damage");
- childDisable("check visible"); // use estates to update...
- childEnable("block terraform");
- childEnable("block dwell");
- childEnable("is sandbox");
+ getChildView("check prelude")->setEnabled(TRUE);
+ getChildView("check fixed sun")->setEnabled(TRUE);
+ getChildView("check reset home")->setEnabled(TRUE);
+ getChildView("check damage")->setEnabled(TRUE);
+ getChildView("check visible")->setEnabled(FALSE); // use estates to update...
+ getChildView("block terraform")->setEnabled(TRUE);
+ getChildView("block dwell")->setEnabled(TRUE);
+ getChildView("is sandbox")->setEnabled(TRUE);
- childEnable("billable factor");
- childEnable("land cost");
+ getChildView("billable factor")->setEnabled(TRUE);
+ getChildView("land cost")->setEnabled(TRUE);
- childDisable("Apply"); // don't enable this one
- childEnable("Bake Terrain");
- childEnable("Autosave now");
+ getChildView("Apply")->setEnabled(FALSE); // don't enable this one
+ getChildView("Bake Terrain")->setEnabled(TRUE);
+ getChildView("Autosave now")->setEnabled(TRUE);
}
-
-// static
void LLPanelRegionTools::onSaveState(void* userdata)
{
if (gAgent.isGodlike())
@@ -602,112 +599,112 @@ void LLPanelRegionTools::onSaveState(void* userdata)
const std::string LLPanelRegionTools::getSimName() const
{
- return childGetValue("region name");
+ return getChild("region name")->getValue();
}
U32 LLPanelRegionTools::getEstateID() const
{
- U32 id = (U32)childGetValue("estate").asInteger();
+ U32 id = (U32)getChild("estate")->getValue().asInteger();
return id;
}
U32 LLPanelRegionTools::getParentEstateID() const
{
- U32 id = (U32)childGetValue("parentestate").asInteger();
+ U32 id = (U32)getChild("parentestate")->getValue().asInteger();
return id;
}
S32 LLPanelRegionTools::getRedirectGridX() const
{
- return childGetValue("redirectx").asInteger();
+ return getChild("redirectx")->getValue().asInteger();
}
S32 LLPanelRegionTools::getRedirectGridY() const
{
- return childGetValue("redirecty").asInteger();
+ return getChild("redirecty")->getValue().asInteger();
}
S32 LLPanelRegionTools::getGridPosX() const
{
- return childGetValue("gridposx").asInteger();
+ return getChild("gridposx")->getValue().asInteger();
}
S32 LLPanelRegionTools::getGridPosY() const
{
- return childGetValue("gridposy").asInteger();
+ return getChild("gridposy")->getValue().asInteger();
}
-U32 LLPanelRegionTools::getRegionFlags() const
+U64 LLPanelRegionTools::getRegionFlags() const
{
- U32 flags = 0x0;
- flags = childGetValue("check prelude").asBoolean()
+ U64 flags = 0x0;
+ flags = getChild("check prelude")->getValue().asBoolean()
? set_prelude_flags(flags)
: unset_prelude_flags(flags);
// override prelude
- if (childGetValue("check fixed sun").asBoolean())
+ if (getChild("check fixed sun")->getValue().asBoolean())
{
flags |= REGION_FLAGS_SUN_FIXED;
}
- if (childGetValue("check reset home").asBoolean())
+ if (getChild("check reset home")->getValue().asBoolean())
{
flags |= REGION_FLAGS_RESET_HOME_ON_TELEPORT;
}
- if (childGetValue("check visible").asBoolean())
+ if (getChild("check visible")->getValue().asBoolean())
{
flags |= REGION_FLAGS_EXTERNALLY_VISIBLE;
}
- if (childGetValue("check damage").asBoolean())
+ if (getChild("check damage")->getValue().asBoolean())
{
flags |= REGION_FLAGS_ALLOW_DAMAGE;
}
- if (childGetValue("block terraform").asBoolean())
+ if (getChild("block terraform")->getValue().asBoolean())
{
flags |= REGION_FLAGS_BLOCK_TERRAFORM;
}
- if (childGetValue("block dwell").asBoolean())
+ if (getChild("block dwell")->getValue().asBoolean())
{
flags |= REGION_FLAGS_BLOCK_DWELL;
}
- if (childGetValue("is sandbox").asBoolean())
+ if (getChild("is sandbox")->getValue().asBoolean())
{
flags |= REGION_FLAGS_SANDBOX;
}
return flags;
}
-U32 LLPanelRegionTools::getRegionFlagsMask() const
+U64 LLPanelRegionTools::getRegionFlagsMask() const
{
- U32 flags = 0xffffffff;
- flags = childGetValue("check prelude").asBoolean()
+ U64 flags = 0xFFFFFFFFFFFFFFFFULL;
+ flags = getChild("check prelude")->getValue().asBoolean()
? set_prelude_flags(flags)
: unset_prelude_flags(flags);
- if (!childGetValue("check fixed sun").asBoolean())
+ if (!getChild("check fixed sun")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_SUN_FIXED;
}
- if (!childGetValue("check reset home").asBoolean())
+ if (!getChild("check reset home")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_RESET_HOME_ON_TELEPORT;
}
- if (!childGetValue("check visible").asBoolean())
+ if (!getChild("check visible")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_EXTERNALLY_VISIBLE;
}
- if (!childGetValue("check damage").asBoolean())
+ if (!getChild("check damage")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_ALLOW_DAMAGE;
}
- if (!childGetValue("block terraform").asBoolean())
+ if (!getChild("block terraform")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_BLOCK_TERRAFORM;
}
- if (!childGetValue("block dwell").asBoolean())
+ if (!getChild("block dwell")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_BLOCK_DWELL;
}
- if (!childGetValue("is sandbox").asBoolean())
+ if (!getChild("is sandbox")->getValue().asBoolean())
{
flags &= ~REGION_FLAGS_SANDBOX;
}
@@ -716,150 +713,145 @@ U32 LLPanelRegionTools::getRegionFlagsMask() const
F32 LLPanelRegionTools::getBillableFactor() const
{
- return (F32)childGetValue("billable factor").asReal();
+ return (F32)getChild("billable factor")->getValue().asReal();
}
S32 LLPanelRegionTools::getPricePerMeter() const
{
- return childGetValue("land cost");
+ return getChild("land cost")->getValue();
}
void LLPanelRegionTools::setSimName(const std::string& name)
{
- childSetValue("region name", name);
+ getChild("region name")->setValue(name);
}
void LLPanelRegionTools::setEstateID(U32 id)
{
- childSetValue("estate", (S32)id);
+ getChild("estate")->setValue((S32)id);
}
void LLPanelRegionTools::setGridPosX(S32 pos)
{
- childSetValue("gridposx", pos);
+ getChild("gridposx")->setValue(pos);
}
void LLPanelRegionTools::setGridPosY(S32 pos)
{
- childSetValue("gridposy", pos);
+ getChild("gridposy")->setValue(pos);
}
void LLPanelRegionTools::setRedirectGridX(S32 pos)
{
- childSetValue("redirectx", pos);
+ getChild("redirectx")->setValue(pos);
}
void LLPanelRegionTools::setRedirectGridY(S32 pos)
{
- childSetValue("redirecty", pos);
+ getChild("redirecty")->setValue(pos);
}
void LLPanelRegionTools::setParentEstateID(U32 id)
{
- childSetValue("parentestate", (S32)id);
+ getChild("parentestate")->setValue((S32)id);
}
-void LLPanelRegionTools::setCheckFlags(U32 flags)
+void LLPanelRegionTools::setCheckFlags(U64 flags)
{
- childSetValue("check prelude", is_prelude(flags) ? TRUE : FALSE);
- childSetValue("check fixed sun", flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE);
- childSetValue("check reset home", flags & REGION_FLAGS_RESET_HOME_ON_TELEPORT ? TRUE : FALSE);
- childSetValue("check damage", flags & REGION_FLAGS_ALLOW_DAMAGE ? TRUE : FALSE);
- childSetValue("check visible", flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE);
- childSetValue("block terraform", flags & REGION_FLAGS_BLOCK_TERRAFORM ? TRUE : FALSE);
- childSetValue("block dwell", flags & REGION_FLAGS_BLOCK_DWELL ? TRUE : FALSE);
- childSetValue("is sandbox", flags & REGION_FLAGS_SANDBOX ? TRUE : FALSE );
+ getChild("check prelude")->setValue(is_prelude(flags) ? TRUE : FALSE);
+ getChild("check fixed sun")->setValue(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE);
+ getChild("check reset home")->setValue(flags & REGION_FLAGS_RESET_HOME_ON_TELEPORT ? TRUE : FALSE);
+ getChild("check damage")->setValue(flags & REGION_FLAGS_ALLOW_DAMAGE ? TRUE : FALSE);
+ getChild("check visible")->setValue(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE);
+ getChild("block terraform")->setValue(flags & REGION_FLAGS_BLOCK_TERRAFORM ? TRUE : FALSE);
+ getChild("block dwell")->setValue(flags & REGION_FLAGS_BLOCK_DWELL ? TRUE : FALSE);
+ getChild("is sandbox")->setValue(flags & REGION_FLAGS_SANDBOX ? TRUE : FALSE );
}
void LLPanelRegionTools::setBillableFactor(F32 billable_factor)
{
- childSetValue("billable factor", billable_factor);
+ getChild("billable factor")->setValue(billable_factor);
}
void LLPanelRegionTools::setPricePerMeter(S32 price)
{
- childSetValue("land cost", price);
+ getChild("land cost")->setValue(price);
}
-// static
-void LLPanelRegionTools::onChangeAnything(LLUICtrl* ctrl, void* userdata)
+void LLPanelRegionTools::onChangeAnything()
{
- if (sGodTools && userdata && gAgent.isGodlike())
+ if (gAgent.isGodlike())
{
- LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata;
- region_tools->childEnable("Apply");
+ getChildView("Apply")->setEnabled(TRUE);
}
}
-// static
-void LLPanelRegionTools::onChangePrelude(LLUICtrl* ctrl, void* data)
+void LLPanelRegionTools::onChangePrelude()
{
// checking prelude auto-checks fixed sun
- LLPanelRegionTools* self = (LLPanelRegionTools*)data;
- if (self->childGetValue("check prelude").asBoolean())
+ if (getChild("check prelude")->getValue().asBoolean())
{
- self->childSetValue("check fixed sun", TRUE);
- self->childSetValue("check reset home", TRUE);
+ getChild("check fixed sun")->setValue(TRUE);
+ getChild("check reset home")->setValue(TRUE);
}
// pass on to default onChange handler
- onChangeAnything(ctrl, data);
+ onChangeAnything();
}
// static
void LLPanelRegionTools::onChangeSimName(LLLineEditor* caller, void* userdata )
{
- if (sGodTools && userdata && gAgent.isGodlike())
+ if (userdata && gAgent.isGodlike())
{
LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata;
- region_tools->childEnable("Apply");
+ region_tools->getChildView("Apply")->setEnabled(TRUE);
}
}
-//static
-void LLPanelRegionTools::onRefresh(void* userdata)
+
+void LLPanelRegionTools::onRefresh()
{
- if(!sGodTools) return;
+ LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL;
+ if(!god_tools) return;
LLViewerRegion *region = gAgent.getRegion();
if (region && gAgent.isGodlike())
{
- sGodTools->sendRegionInfoRequest();
+ god_tools->sendRegionInfoRequest();
+ //LLFloaterGodTools::getInstance()->sendRegionInfoRequest();
+ //LLFloaterReg::getTypedInstance("god_tools")->sendRegionInfoRequest();
}
}
-// static
-void LLPanelRegionTools::onApplyChanges(void* userdata)
+void LLPanelRegionTools::onApplyChanges()
{
- if(!sGodTools) return;
+ LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL;
+ if(!god_tools) return;
LLViewerRegion *region = gAgent.getRegion();
- if (region && userdata && gAgent.isGodlike())
+ if (region && gAgent.isGodlike())
{
- LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata;
-
- region_tools->childDisable("Apply");
- sGodTools->sendGodUpdateRegionInfo();
+ getChildView("Apply")->setEnabled(FALSE);
+ god_tools->sendGodUpdateRegionInfo();
+ //LLFloaterReg::getTypedInstance("god_tools")->sendGodUpdateRegionInfo();
}
}
-// static
-void LLPanelRegionTools::onBakeTerrain(void *userdata)
+void LLPanelRegionTools::onBakeTerrain()
{
LLPanelRequestTools::sendRequest("terrain", "bake", gAgent.getRegionHost());
}
-// static
-void LLPanelRegionTools::onRevertTerrain(void *userdata)
+void LLPanelRegionTools::onRevertTerrain()
{
LLPanelRequestTools::sendRequest("terrain", "revert", gAgent.getRegionHost());
}
-// static
-void LLPanelRegionTools::onSwapTerrain(void *userdata)
+
+void LLPanelRegionTools::onSwapTerrain()
{
LLPanelRequestTools::sendRequest("terrain", "swap", gAgent.getRegionHost());
}
-// static
-void LLPanelRegionTools::onSelectRegion(void* userdata)
+void LLPanelRegionTools::onSelectRegion()
{
llinfos << "LLPanelRegionTools::onSelectRegion" << llendl;
@@ -914,8 +906,8 @@ LLPanelGridTools::~LLPanelGridTools()
BOOL LLPanelGridTools::postBuild()
{
- childSetAction("Kick all users", onClickKickAll, this);
- childSetAction("Flush This Region's Map Visibility Caches", onClickFlushMapVisibilityCaches, this);
+ childSetAction("Kick all users", boost::bind(&LLPanelGridTools::onClickKickAll, this));
+ childSetAction("Flush This Region's Map Visibility Caches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this));
return TRUE;
}
@@ -925,17 +917,12 @@ void LLPanelGridTools::refresh()
}
-// static
-void LLPanelGridTools::onClickKickAll(void* userdata)
+void LLPanelGridTools::onClickKickAll()
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect(left, top, left+400, top-300);
-
LLNotificationsUtil::add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick);
}
-
+// static
bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& response)
{
if (LLNotification::getSelectedOption(notification, response) == 0)
@@ -947,7 +934,6 @@ bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& respons
return false;
}
-
// static
bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response)
{
@@ -969,9 +955,7 @@ bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response
return false;
}
-
-// static
-void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data)
+void LLPanelGridTools::onClickFlushMapVisibilityCaches()
{
LLNotificationsUtil::add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm);
}
@@ -979,7 +963,7 @@ void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data)
// static
bool LLPanelGridTools::flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option != 0) return false;
// HACK: Send this as an EstateOwnerRequest so it gets routed
@@ -1039,22 +1023,23 @@ LLPanelObjectTools::~LLPanelObjectTools()
BOOL LLPanelObjectTools::postBuild()
{
- childSetCommitCallback("disable scripts", onChangeAnything, this);
- childSetCommitCallback("disable collisions", onChangeAnything, this);
- childSetCommitCallback("disable physics", onChangeAnything, this);
+ getChild