diff --git a/.hgtags b/.hgtags index c9870bfb0fc32b216e228285b6cb696dcf3070ab..730e86e16a64ed48832f7f24a1ff8712c5f6e5a8 100755 --- a/.hgtags +++ b/.hgtags @@ -521,3 +521,4 @@ e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release 45eaee56883df7a439ed3300c44d3126f7e3a41e 4.0.8-release b280a1c797a3891e68dbc237e73de9cf19f426e9 4.1.1-release bfbba2244320dc2ae47758cd7edd8fa3b67dc756 4.1.2-release +b41e1e7c7876f7656c505f552b5888b4e478f92b 5.0.0-release diff --git a/doc/contributions.txt b/doc/contributions.txt index f7d1ece72fe3896adb0952d7946333a6bf630ec8..521be7b7e2318a47e4d42de625a34ae7f95655ee 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -12,6 +12,7 @@ Able Whitman Adam Marker VWR-2755 Adeon Writer + MAINT-1211 Aeonix Aeon Agathos Frascati CT-246 @@ -317,6 +318,7 @@ Catherine Pfeffer VWR-1282 VWR-8624 VWR-10854 +Cathy Foil Cayu Cluny Celierra Darling VWR-1274 @@ -870,6 +872,7 @@ MartinRJ Fayray STORM-1845 STORM-1911 STORM-1934 +Matrice Laville Matthew Anthony Matthew Dowd VWR-1344 @@ -1244,6 +1247,7 @@ Shnurui Troughton Shyotl Kuhr MAINT-1138 MAINT-2334 + MAINT-6913 Siana Gearz STORM-960 STORM-1088 @@ -1277,6 +1281,7 @@ Sovereign Engineer MAINT-6107 STORM-2107 MAINT-6218 + MAINT-6913 SpacedOut Frye VWR-34 VWR-45 diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index d1eb38901316b25621b1666c1ee62297cc977a2f..94c431feb4a30e9634350d41de4ac9c5fe340bba 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -44,6 +44,7 @@ #include "lltexglobalcolor.h" #include "llwearabledata.h" #include "boost/bind.hpp" +#include "boost/tokenizer.hpp" #if LL_MSVC @@ -87,8 +88,11 @@ class LLAvatarBoneInfo private: std::string mName; + std::string mSupport; + std::string mAliases; BOOL mIsJoint; LLVector3 mPos; + LLVector3 mEnd; LLVector3 mRot; LLVector3 mScale; LLVector3 mPivot; @@ -118,6 +122,7 @@ class LLAvatarSkeletonInfo private: S32 mNumBones; S32 mNumCollisionVolumes; + LLAvatarAppearance::joint_alias_map_t mJointAliasMap; typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t; bone_info_list_t mBoneInfoList; }; @@ -181,7 +186,11 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mPelvisToFoot(0.f), mHeadOffset(), mRoot(NULL), - mWearableData(wearable_data) + mWearableData(wearable_data), + mNumBones(0), + mNumCollisionVolumes(0), + mCollisionVolumes(NULL), + mIsBuilt(FALSE) { llassert_always(mWearableData); mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES); @@ -194,11 +203,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mBakedTextureDatas[i].mMaskTexName = 0; mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i); } - - mIsBuilt = FALSE; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; } // virtual @@ -323,36 +327,49 @@ LLAvatarAppearance::~LLAvatarAppearance() //static void LLAvatarAppearance::initClass() { - std::string xmlFile; + initClass("",""); +} - xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; - BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); +//static +void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, const std::string& skeleton_file_name_arg) +{ + std::string avatar_file_name; + + if (!avatar_file_name_arg.empty()) + { + avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,avatar_file_name_arg); + } + else + { + avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR + "_lad.xml"); + } + BOOL success = sXMLTree.parseFile( avatar_file_name, FALSE ); if (!success) { - LL_ERRS() << "Problem reading avatar configuration file:" << xmlFile << LL_ENDL; + LL_ERRS() << "Problem reading avatar configuration file:" << avatar_file_name << LL_ENDL; } // now sanity check xml file LLXmlTreeNode* root = sXMLTree.getRoot(); if (!root) { - LL_ERRS() << "No root node found in avatar configuration file: " << xmlFile << LL_ENDL; + LL_ERRS() << "No root node found in avatar configuration file: " << avatar_file_name << LL_ENDL; return; } //------------------------------------------------------------------------- - // <linden_avatar version="1.0"> (root) + // <linden_avatar version="2.0"> (root) //------------------------------------------------------------------------- if( !root->hasName( "linden_avatar" ) ) { - LL_ERRS() << "Invalid avatar file header: " << xmlFile << LL_ENDL; + LL_ERRS() << "Invalid avatar file header: " << avatar_file_name << LL_ENDL; } std::string version; static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + if( !root->getFastAttributeString( version_string, version ) || ((version != "1.0") && (version != "2.0"))) { - LL_ERRS() << "Invalid avatar file version: " << version << " in file: " << xmlFile << LL_ENDL; + LL_ERRS() << "Invalid avatar file version: " << version << " in file: " << avatar_file_name << LL_ENDL; } S32 wearable_def_version = 1; @@ -365,16 +382,19 @@ void LLAvatarAppearance::initClass() LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); if (!skeleton_node) { - LL_ERRS() << "No skeleton in avatar configuration file: " << xmlFile << LL_ENDL; + LL_ERRS() << "No skeleton in avatar configuration file: " << avatar_file_name << LL_ENDL; 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)) - { - LL_ERRS() << "No file name in skeleton node in avatar config file: " << xmlFile << LL_ENDL; - } + + std::string skeleton_file_name = skeleton_file_name_arg; + if (skeleton_file_name.empty()) + { + static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); + if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name)) + { + LL_ERRS() << "No file name in skeleton node in avatar config file: " << avatar_file_name << LL_ENDL; + } + } std::string skeleton_path; skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); @@ -437,11 +457,56 @@ void LLAvatarAppearance::cleanupClass() using namespace LLAvatarAppearanceDefines; +void LLAvatarAppearance::compareJointStateMaps(joint_state_map_t& last_state, + joint_state_map_t& curr_state) +{ + if (!last_state.empty() && (last_state != curr_state)) + { + S32 diff_count = 0; + joint_state_map_t::iterator it; + for (it=last_state.begin(); it != last_state.end(); ++it) + { + const std::string& key = it->first; + if (last_state[key] != curr_state[key]) + { + LL_DEBUGS("AvatarBodySize") << "BodySize change " << key << " " << last_state[key] << "->" << curr_state[key] << LL_ENDL; + diff_count++; + } + } + if (diff_count > 0) + { + LL_DEBUGS("AvatarBodySize") << "Total of BodySize changes " << diff_count << LL_ENDL; + } + + } +} + //------------------------------------------------------------------------ // The viewer can only suggest a good size for the agent, // the simulator will keep it inside a reasonable range. void LLAvatarAppearance::computeBodySize() { + mLastBodySizeState = mCurrBodySizeState; + + mCurrBodySizeState["mPelvis scale"] = mPelvisp->getScale(); + mCurrBodySizeState["mSkull pos"] = mSkullp->getPosition(); + mCurrBodySizeState["mSkull scale"] = mSkullp->getScale(); + mCurrBodySizeState["mNeck pos"] = mNeckp->getPosition(); + mCurrBodySizeState["mNeck scale"] = mNeckp->getScale(); + mCurrBodySizeState["mChest pos"] = mChestp->getPosition(); + mCurrBodySizeState["mChest scale"] = mChestp->getScale(); + mCurrBodySizeState["mHead pos"] = mHeadp->getPosition(); + mCurrBodySizeState["mHead scale"] = mHeadp->getScale(); + mCurrBodySizeState["mTorso pos"] = mTorsop->getPosition(); + mCurrBodySizeState["mTorso scale"] = mTorsop->getScale(); + mCurrBodySizeState["mHipLeft pos"] = mHipLeftp->getPosition(); + mCurrBodySizeState["mHipLeft scale"] = mHipLeftp->getScale(); + mCurrBodySizeState["mKneeLeft pos"] = mKneeLeftp->getPosition(); + mCurrBodySizeState["mKneeLeft scale"] = mKneeLeftp->getScale(); + mCurrBodySizeState["mAnkleLeft pos"] = mAnkleLeftp->getPosition(); + mCurrBodySizeState["mAnkleLeft scale"] = mAnkleLeftp->getScale(); + mCurrBodySizeState["mFootLeft pos"] = mFootLeftp->getPosition(); + LLVector3 pelvis_scale = mPelvisp->getScale(); // some of the joints have not been cached @@ -501,6 +566,8 @@ void LLAvatarAppearance::computeBodySize() if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ]) { mBodySize = new_body_size; + + compareJointStateMaps(mLastBodySizeState, mCurrBodySizeState); } } @@ -536,7 +603,7 @@ BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename) std::string version; static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + if( !root->getFastAttributeString( version_string, version ) || ((version != "1.0") && (version != "2.0"))) { LL_ERRS() << "Invalid avatar skeleton file version: " << version << " in file: " << filename << LL_ENDL; return FALSE; @@ -552,6 +619,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent { LLJoint* joint = NULL; + LL_DEBUGS("BVH") << "bone info: name " << info->mName + << " isJoint " << info->mIsJoint + << " volume_num " << volume_num + << " joint_num " << joint_num + << LL_ENDL; + if (info->mIsJoint) { joint = getCharacterJoint(joint_num); @@ -566,7 +639,7 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent { if (volume_num >= (S32)mNumCollisionVolumes) { - LL_WARNS() << "Too many bones" << LL_ENDL; + LL_WARNS() << "Too many collision volumes" << LL_ENDL; return FALSE; } joint = (&mCollisionVolumes[volume_num]); @@ -574,26 +647,34 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent } // add to parent - if (parent) + if (parent && (joint->getParent()!=parent)) { parent->addChild( joint ); } + // SL-315 joint->setPosition(info->mPos); + joint->setDefaultPosition(info->mPos); joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], info->mRot.mV[VZ], LLQuaternion::XYZ)); joint->setScale(info->mScale); + joint->setDefaultScale(info->mScale); + joint->setSupport(info->mSupport); + joint->setEnd(info->mEnd); if (info->mIsJoint) { joint->setSkinOffset( info->mPivot ); + joint->setJointNum(joint_num); joint_num++; } else // collision volume { + joint->setJointNum(mNumBones+volume_num); volume_num++; } + // setup children LLAvatarBoneInfo::child_list_t::const_iterator iter; for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) @@ -613,12 +694,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent //----------------------------------------------------------------------------- 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.size() != num) + { + clearSkeleton(); + mSkeleton = avatar_joint_list_t(num,NULL); + mNumBones = num; + } return TRUE; } @@ -629,18 +710,16 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num ) //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) { - //------------------------------------------------------------------------- + LL_DEBUGS("BVH") << "numBones " << info->mNumBones << " numCollisionVolumes " << info->mNumCollisionVolumes << LL_ENDL; + // allocate joints - //------------------------------------------------------------------------- if (!allocateCharacterJoints(info->mNumBones)) { LL_ERRS() << "Can't allocate " << info->mNumBones << " joints" << LL_ENDL; return FALSE; } - //------------------------------------------------------------------------- // allocate volumes - //------------------------------------------------------------------------- if (info->mNumCollisionVolumes) { if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) @@ -655,8 +734,8 @@ BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) 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)) + LLAvatarBoneInfo *bone_info = *iter; + if (!setupBone(bone_info, NULL, current_volume_num, current_joint_num)) { LL_ERRS() << "Error parsing bone in skeleton file" << LL_ENDL; return FALSE; @@ -820,6 +899,7 @@ void LLAvatarAppearance::buildCharacter() //------------------------------------------------------------------------- // initialize the pelvis //------------------------------------------------------------------------- + // SL-315 mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); mIsBuilt = TRUE; @@ -834,21 +914,21 @@ BOOL LLAvatarAppearance::loadAvatar() // avatar_skeleton.xml if( !buildSkeleton(sAvatarSkeletonInfo) ) { - LL_WARNS() << "avatar file: buildSkeleton() failed" << LL_ENDL; + LL_ERRS() << "avatar file: buildSkeleton() failed" << LL_ENDL; return FALSE; } // avatar_lad.xml : <skeleton> if( !loadSkeletonNode() ) { - LL_WARNS() << "avatar file: loadNodeSkeleton() failed" << LL_ENDL; + LL_ERRS() << "avatar file: loadNodeSkeleton() failed" << LL_ENDL; return FALSE; } // avatar_lad.xml : <mesh> if( !loadMeshNodes() ) { - LL_WARNS() << "avatar file: loadNodeMesh() failed" << LL_ENDL; + LL_ERRS() << "avatar file: loadNodeMesh() failed" << LL_ENDL; return FALSE; } @@ -858,13 +938,13 @@ BOOL LLAvatarAppearance::loadAvatar() mTexSkinColor = new LLTexGlobalColor( this ); if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) { - LL_WARNS() << "avatar file: mTexSkinColor->setInfo() failed" << LL_ENDL; + LL_ERRS() << "avatar file: mTexSkinColor->setInfo() failed" << LL_ENDL; return FALSE; } } else { - LL_WARNS() << "<global_color> name=\"skin_color\" not found" << LL_ENDL; + LL_ERRS() << "<global_color> name=\"skin_color\" not found" << LL_ENDL; return FALSE; } if( sAvatarXmlInfo->mTexHairColorInfo ) @@ -872,13 +952,13 @@ BOOL LLAvatarAppearance::loadAvatar() mTexHairColor = new LLTexGlobalColor( this ); if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) ) { - LL_WARNS() << "avatar file: mTexHairColor->setInfo() failed" << LL_ENDL; + LL_ERRS() << "avatar file: mTexHairColor->setInfo() failed" << LL_ENDL; return FALSE; } } else { - LL_WARNS() << "<global_color> name=\"hair_color\" not found" << LL_ENDL; + LL_ERRS() << "<global_color> name=\"hair_color\" not found" << LL_ENDL; return FALSE; } if( sAvatarXmlInfo->mTexEyeColorInfo ) @@ -886,26 +966,26 @@ BOOL LLAvatarAppearance::loadAvatar() mTexEyeColor = new LLTexGlobalColor( this ); if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) ) { - LL_WARNS() << "avatar file: mTexEyeColor->setInfo() failed" << LL_ENDL; + LL_ERRS() << "avatar file: mTexEyeColor->setInfo() failed" << LL_ENDL; return FALSE; } } else { - LL_WARNS() << "<global_color> name=\"eye_color\" not found" << LL_ENDL; + LL_ERRS() << "<global_color> name=\"eye_color\" not found" << LL_ENDL; return FALSE; } // avatar_lad.xml : <layer_set> if (sAvatarXmlInfo->mLayerInfoList.empty()) { - LL_WARNS() << "avatar file: missing <layer_set> node" << LL_ENDL; + LL_ERRS() << "avatar file: missing <layer_set> node" << LL_ENDL; return FALSE; } if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) { - LL_WARNS() << "avatar file: missing <morph_masks> node" << LL_ENDL; + LL_ERRS() << "avatar file: missing <morph_masks> node" << LL_ENDL; return FALSE; } @@ -1104,6 +1184,7 @@ BOOL LLAvatarAppearance::loadMeshNodes() { // This should never happen LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL; + return FALSE; } } else @@ -1240,6 +1321,10 @@ LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num ) { return NULL; } + if (!mSkeleton[num]) + { + mSkeleton[num] = createAvatarJoint(); + } return mSkeleton[num]; } @@ -1476,16 +1561,19 @@ LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_in //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) { - delete_and_clear_array(mCollisionVolumes); - mNumCollisionVolumes = 0; - - mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; - if (!mCollisionVolumes) - { - return FALSE; - } - - mNumCollisionVolumes = num; + if (mNumCollisionVolumes !=num) + { + delete_and_clear_array(mCollisionVolumes); + mNumCollisionVolumes = 0; + + mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; + if (!mCollisionVolumes) + { + return FALSE; + } + + mNumCollisionVolumes = num; + } return TRUE; } @@ -1503,6 +1591,9 @@ BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) LL_WARNS() << "Bone without name" << LL_ENDL; return FALSE; } + + static LLStdStringHandle aliases_string = LLXmlTree::addAttributeString("aliases"); + node->getFastAttributeString(aliases_string, mAliases ); //Aliases are not required. } else if (node->hasName("collision_volume")) { @@ -1540,6 +1631,20 @@ BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) return FALSE; } + static LLStdStringHandle end_string = LLXmlTree::addAttributeString("end"); + if (!node->getFastAttributeVector3(end_string, mEnd)) + { + LL_WARNS() << "Bone without end " << mName << LL_ENDL; + mEnd = LLVector3(0.0f, 0.0f, 0.0f); + } + + static LLStdStringHandle support_string = LLXmlTree::addAttributeString("support"); + if (!node->getFastAttributeString(support_string,mSupport)) + { + LL_WARNS() << "Bone without support " << mName << LL_ENDL; + mSupport = "base"; + } + if (mIsJoint) { static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); @@ -1595,6 +1700,54 @@ BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) return TRUE; } +//Make aliases for joint and push to map. +void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info) +{ + if (! bone_info->mIsJoint ) + { + return; + } + + std::string bone_name = bone_info->mName; + mJointAliasMap[bone_name] = bone_name; //Actual name is a valid alias. + + std::string aliases = bone_info->mAliases; + + boost::char_separator<char> sep(" "); + boost::tokenizer<boost::char_separator<char> > tok(aliases, sep); + for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i) + { + if ( mJointAliasMap.find(*i) != mJointAliasMap.end() ) + { + LL_WARNS() << "avatar skeleton: Joint alias \"" << *i << "\" remapped from " << mJointAliasMap[*i] << " to " << bone_name << LL_ENDL; + } + mJointAliasMap[*i] = bone_name; + } + + LLAvatarBoneInfo::child_list_t::const_iterator iter; + for (iter = bone_info->mChildList.begin(); iter != bone_info->mChildList.end(); ++iter) + { + makeJointAliases( *iter ); + } +} + +const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases () +{ + LLAvatarAppearance::joint_alias_map_t alias_map; + if (mJointAliasMap.empty()) + { + + LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; + for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin(); iter != sAvatarSkeletonInfo->mBoneInfoList.end(); ++iter) + { + //LLAvatarBoneInfo *bone_info = *iter; + makeJointAliases( *iter ); + } + } + + return mJointAliasMap; +} + //----------------------------------------------------------------------------- // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree @@ -1625,7 +1778,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "Unknown param type." << LL_ENDL; } - continue; + return FALSE; } LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; @@ -1650,7 +1803,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "No name supplied for attachment point." << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); @@ -1658,7 +1811,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "No bone declared in attachment point " << info->mName << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); @@ -1684,7 +1837,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "No id supplied for attachment point " << info->mName << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); @@ -1770,7 +1923,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) { LL_WARNS() << "Unknown param type." << LL_ENDL; } - continue; + return FALSE; } LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); @@ -1931,7 +2084,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root { LL_WARNS() << "No name supplied for morph mask." << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region"); @@ -1939,7 +2092,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root { LL_WARNS() << "No region supplied for morph mask." << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer"); @@ -1947,7 +2100,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root { LL_WARNS() << "No layer supplied for morph mask." << LL_ENDL; delete info; - continue; + return FALSE; } // optional parameter. don't throw a warning if not present. diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index a0ef49b7cb520e75b6bc94a4b839e1909691703f..ccd6323ed85e86cd327174360ac53dd9eba8808c 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -66,7 +66,8 @@ class LLAvatarAppearance : public LLCharacter LLAvatarAppearance(LLWearableData* wearable_data); virtual ~LLAvatarAppearance(); - static void initClass(); // initializes static members + static void initClass(const std::string& avatar_file_name, const std::string& skeleton_file_name); // initializes static members + static void initClass(); 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(); @@ -124,8 +125,11 @@ class LLAvatarAppearance : public LLCharacter protected: virtual LLAvatarJoint* createAvatarJoint() = 0; - virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0; + virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0; virtual LLAvatarJointMesh* createAvatarJointMesh() = 0; + void makeJointAliases(LLAvatarBoneInfo *bone_info); + + public: F32 getPelvisToFoot() const { return mPelvisToFoot; } /*virtual*/ LLJoint* getRootJoint() { return mRoot; } @@ -135,9 +139,20 @@ class LLAvatarAppearance : public LLCharacter typedef std::map<std::string, LLJoint*> joint_map_t; joint_map_t mJointMap; - + + typedef std::map<std::string, LLVector3> joint_state_map_t; + joint_state_map_t mLastBodySizeState; + joint_state_map_t mCurrBodySizeState; + void compareJointStateMaps(joint_state_map_t& last_state, + joint_state_map_t& curr_state); void computeBodySize(); +public: + typedef std::vector<LLAvatarJoint*> avatar_joint_list_t; + const avatar_joint_list_t& getSkeleton() { return mSkeleton; } + typedef std::map<std::string, std::string> joint_alias_map_t; + const joint_alias_map_t& getJointAliases(); + protected: static BOOL parseSkeletonFile(const std::string& filename); @@ -147,12 +162,12 @@ class LLAvatarAppearance : public LLCharacter 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<LLAvatarJoint*> avatar_joint_list_t; avatar_joint_list_t mSkeleton; - LLPosOverrideMap mPelvisFixups; + LLVector3OverrideMap mPelvisFixups; + joint_alias_map_t mJointAliasMap; //-------------------------------------------------------------------- // Pelvis height adjustment members. @@ -335,6 +350,7 @@ class LLAvatarAppearance : public LLCharacter // Collision volumes //-------------------------------------------------------------------- public: + S32 mNumBones; S32 mNumCollisionVolumes; LLAvatarJointCollisionVolume* mCollisionVolumes; protected: diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp index 2ee3c65a01ddef2a2cde2a688fe40ffa5afb4261..29642be099a3d9c26c3fed801f332cf892ee948d 100644 --- a/indra/llappearance/llavatarjoint.cpp +++ b/indra/llappearance/llavatarjoint.cpp @@ -52,19 +52,18 @@ LLAvatarJoint::LLAvatarJoint() : init(); } -LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) : - LLJoint(name, parent) +LLAvatarJoint::LLAvatarJoint(S32 joint_num) : + LLJoint(joint_num) { - init(); + init(); } - -LLAvatarJoint::LLAvatarJoint(S32 joint_num) : - LLJoint(joint_num) + +LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) : + LLJoint(name, parent) { init(); } - void LLAvatarJoint::init() { mValid = FALSE; diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp index 520ad775db7cbc46c59a1c95b5bf01167f69325f..7ca0928171f55ab33a00832b9ac8948baf84f715 100644 --- a/indra/llappearance/llavatarjointmesh.cpp +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -33,22 +33,7 @@ #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" @@ -56,6 +41,41 @@ #include "llmatrix4a.h" +// Utility functions added with Bento to simplify handling of extra +// spine joints, or other new joints internal to the original +// skeleton, and unknown to the system avatar. + +//----------------------------------------------------------------------------- +// getBaseSkeletonAncestor() +//----------------------------------------------------------------------------- +LLAvatarJoint *getBaseSkeletonAncestor(LLAvatarJoint* joint) +{ + LLJoint *ancestor = joint->getParent(); + while (ancestor->getParent() && (ancestor->getSupport() != LLJoint::SUPPORT_BASE)) + { + LL_DEBUGS("Avatar") << "skipping non-base ancestor " << ancestor->getName() << LL_ENDL; + ancestor = ancestor->getParent(); + } + return (LLAvatarJoint*) ancestor; +} + +//----------------------------------------------------------------------------- +// totalSkinOffset() +//----------------------------------------------------------------------------- +LLVector3 totalSkinOffset(LLAvatarJoint *joint) +{ + LLVector3 totalOffset; + while (joint) + { + if (joint->getSupport() == LLJoint::SUPPORT_BASE) + { + totalOffset += joint->getSkinOffset(); + } + joint = (LLAvatarJoint*)joint->getParent(); + } + return totalOffset; +} + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLAvatarJointMesh::LLSkinJoint @@ -92,18 +112,12 @@ BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint) } // compute the inverse root skin matrix - mRootToJointSkinOffset.clearVec(); - - LLVector3 rootSkinOffset; - while (joint) - { - rootSkinOffset += joint->getSkinOffset(); - joint = (LLAvatarJoint*)joint->getParent(); - } + mRootToJointSkinOffset = totalSkinOffset(joint); + mRootToJointSkinOffset = -mRootToJointSkinOffset; - mRootToJointSkinOffset = -rootSkinOffset; - mRootToParentJointSkinOffset = mRootToJointSkinOffset; - mRootToParentJointSkinOffset += mJoint->getSkinOffset(); + //mRootToParentJointSkinOffset = totalSkinOffset((LLAvatarJoint*)joint->getParent()); + mRootToParentJointSkinOffset = totalSkinOffset(getBaseSkeletonAncestor(joint)); + mRootToParentJointSkinOffset = -mRootToParentJointSkinOffset; return TRUE; } @@ -289,6 +303,7 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) } // acquire the transform from the mesh object + // SL-315 setPosition( mMesh->getPosition() ); setRotation( mMesh->getRotation() ); setScale( mMesh->getScale() ); @@ -314,9 +329,9 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) if (!mMesh->isLOD()) { setupJoint((LLAvatarJoint*)getRoot()); + LL_DEBUGS("Avatar") << getName() << " joint render entries: " << mMesh->mJointRenderData.size() << LL_ENDL; } - LL_DEBUGS() << "joint render entries: " << mMesh->mJointRenderData.size() << LL_ENDL; } //----------------------------------------------------------------------------- @@ -324,9 +339,6 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) //----------------------------------------------------------------------------- void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) { - LL_DEBUGS() << "Mesh: " << getName() << LL_ENDL; - - S32 joint_count = 0; U32 sj; for (sj=0; sj<mNumSkinJoints; sj++) @@ -339,22 +351,30 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) } // we've found a skinjoint for this joint.. + LL_DEBUGS("Avatar") << "Mesh: " << getName() << " joint " << current_joint->getName() << " matches skinjoint " << sj << LL_ENDL; // is the last joint in the array our parent? - if(mMesh->mJointRenderData.size() && mMesh->mJointRenderData[mMesh->mJointRenderData.size() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) + + std::vector<LLJointRenderData*> &jrd = mMesh->mJointRenderData; + + // SL-287 - need to update this so the results are the same if + // additional extended-skeleton joints lie between this joint + // and the original parent. + LLJoint *ancestor = getBaseSkeletonAncestor(current_joint); + if(jrd.size() && jrd.back()->mWorldMatrix == &ancestor->getWorldMatrix()) { // ...then just add ourselves LLAvatarJoint* jointp = js.mJoint; - mMesh->mJointRenderData.push_back(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); - LL_DEBUGS() << "joint " << joint_count++ << js.mJoint->getName() << LL_ENDL; + jrd.push_back(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); + LL_DEBUGS("Avatar") << "add joint[" << (jrd.size()-1) << "] = " << js.mJoint->getName() << LL_ENDL; } - // otherwise add our parent and ourselves + // otherwise add our ancestor and ourselves else { - mMesh->mJointRenderData.push_back(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL)); - LL_DEBUGS() << "joint " << joint_count++ << current_joint->getParent()->getName() << LL_ENDL; - mMesh->mJointRenderData.push_back(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); - LL_DEBUGS() << "joint " << joint_count++ << current_joint->getName() << LL_ENDL; + jrd.push_back(new LLJointRenderData(&ancestor->getWorldMatrix(), NULL)); + LL_DEBUGS("Avatar") << "add2 ancestor joint[" << (jrd.size()-1) << "] = " << ancestor->getName() << LL_ENDL; + jrd.push_back(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); + LL_DEBUGS("Avatar") << "add2 joint[" << (jrd.size()-1) << "] = " << current_joint->getName() << LL_ENDL; } } diff --git a/indra/llappearance/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp index e630c1118bc859c71c8c0911e3ceb6ec0d0a144b..e5e502b158fd72b3d7e3bc4bfce10bc9635d1da6 100644 --- a/indra/llappearance/lldriverparam.cpp +++ b/indra/llappearance/lldriverparam.cpp @@ -110,6 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out) out << std::endl; + // FIXME - this mDriverParam backlink makes no sense, because the + // LLDriverParamInfos are static objects - there's only one copy + // for each param type, so the backlink will just reference the + // corresponding param in the most recently created + // avatar. Apparently these toStream() methods are not currently + // used anywhere, so it's not an urgent problem. + LL_WARNS_ONCE() << "Invalid usage of mDriverParam." << LL_ENDL; + if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() && mDriverParam->getAvatarAppearance()->isValid()) { diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h index f71c930e5e3716fbf67683690f9f372fd5f02142..f278dcc2e29b0746afa157676bcf88603f832967 100644 --- a/indra/llappearance/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -128,6 +128,10 @@ class LLDriverParam : public LLViewerVisualParam S32 getDrivenParamsCount() const; const LLViewerVisualParam* getDrivenParam(S32 index) const; + typedef std::vector<LLDrivenEntry> entry_list_t; + entry_list_t& getDrivenList() { return mDriven; } + void setDrivenList(entry_list_t& driven_list) { mDriven = driven_list; } + protected: LLDriverParam(const LLDriverParam& pOther); F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); @@ -135,7 +139,6 @@ class LLDriverParam : public LLViewerVisualParam LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder - typedef std::vector<LLDrivenEntry> entry_list_t; entry_list_t mDriven; LLViewerVisualParam* mCurrentDistortionParam; // Backlink only; don't make this an LLPointer. diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index e3992a080e4b02d93c0be859e9a69100ccb4ed01..2cb4c65d7c49a197f1e871397c010a6038c6265f 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -369,7 +369,8 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) { if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName) { - mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], + mVolumeMorphs.push_back( + LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], volume_info->mScale, volume_info->mPos)); break; @@ -647,6 +648,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) LLVector3 pos_delta = volume_morph->mPos * delta_weight; volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); + // SL-315 volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); } } @@ -730,6 +732,20 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3 apply(mLastSex); } +void LLPolyMorphTarget::applyVolumeChanges(F32 delta_weight) +{ + // now apply volume changes + for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ ) + { + LLPolyVolumeMorph* volume_morph = &(*iter); + LLVector3 scale_delta = volume_morph->mScale * delta_weight; + LLVector3 pos_delta = volume_morph->mPos * delta_weight; + + volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); + // SL-315 + volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); + } +} //----------------------------------------------------------------------------- // LLPolyVertexMask() diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h index 3c2c68079c39d29169dbc3083b96ab77aaa3da93..c6133cd83119605a7f2085db8ea9e1f37966658b 100644 --- a/indra/llappearance/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -182,6 +182,8 @@ class LLPolyMorphTarget : public LLViewerVisualParam void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert); void addPendingMorphMask() { mNumMorphMasksPending++; } + void applyVolumeChanges(F32 delta_weight); // SL-315 - for resetSkeleton() + void* operator new(size_t size) { return ll_aligned_malloc_16(size); diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index fbc312c42642923f9700db09cb0898d27cd232f7..5b77a7433ac3d50e1f8bb96620f7fa7d824a7c6c 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -34,6 +34,7 @@ #include "llpolymorph.h" #include "llwearable.h" #include "llfasttimer.h" +#include "llcallstack.h" #include "llpolyskeletaldistortion.h" @@ -134,55 +135,49 @@ LLPolySkeletalDistortion::~LLPolySkeletalDistortion() BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) { - llassert(mInfo == NULL); - if (info->mID < 0) - return FALSE; - mInfo = info; - mID = info->mID; - setWeight(getDefaultWeight()); - - LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter; - for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++) + if (info->mID < 0) + { + return FALSE; + } + mInfo = info; + mID = info->mID; + setWeight(getDefaultWeight()); + + 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) { - LLPolySkeletalBoneInfo *bone_info = &(*iter); - LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName); - if (!joint) - { - LL_WARNS() << "Joint " << bone_info->mBoneName << " not found." << LL_ENDL; - continue; - } - - if (mJointScales.find(joint) != mJointScales.end()) - { - LL_WARNS() << "Scale deformation already supplied for joint " << joint->getName() << "." << LL_ENDL; - } + // There's no point continuing after this error - means + // that either the skeleton or lad file is broken. + LL_WARNS() << "Joint " << bone_info->mBoneName << " not found." << LL_ENDL; + return FALSE; + } - // store it - mJointScales[joint] = bone_info->mScaleDeformation; + // 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) - { - LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); - if (child_joint->inheritScale()) - { - LLVector3 childDeformation = LLVector3(child_joint->getScale()); - childDeformation.scaleVec(bone_info->mScaleDeformation); - mJointScales[child_joint] = childDeformation; - } - } + // apply to children that need to inherit it + for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); + iter != joint->mChildren.end(); ++iter) + { + LLAvatarJoint* child_joint = (LLAvatarJoint*)(*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()) - { - LL_WARNS() << "Offset deformation already supplied for joint " << joint->getName() << "." << LL_ENDL; - } - mJointOffsets[joint] = bone_info->mPositionDeformation; - } + if (bone_info->mHasPositionDeformation) + { + mJointOffsets[joint] = bone_info->mPositionDeformation; } - return TRUE; + } + return TRUE; } /*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const @@ -197,42 +192,52 @@ static LLTrace::BlockTimerStatHandle FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { - LL_RECORD_BLOCK_TIME(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); - //An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached - // needed? // joint->storeScaleForReset( newScale ); - 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; + LL_RECORD_BLOCK_TIME(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; + LLVector3 offset = (effective_weight - mLastWeight) * scaleDelta; + newScale = newScale + offset; + //An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached + // needed? + // joint->storeScaleForReset( newScale ); + + // BENTO for detailed stack tracing of params. + std::stringstream ostr; + ostr << "LLPolySkeletalDistortion::apply, id " << getID() << " " << getName() << " effective wt " << effective_weight << " last wt " << mLastWeight << " scaleDelta " << scaleDelta << " offset " << offset; + LLScopedContextString str(ostr.str()); + + joint->setScale(newScale, true); + } + + 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); + // SL-315 + bool allow_attachment_pos_overrides = true; + joint->setPosition(newPosition, allow_attachment_pos_overrides); + } + + if (mLastWeight != effective_weight && !mIsAnimating) + { + mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); + } + mLastWeight = effective_weight; } diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 5ca9f55ac8ce9d33fa2a4cb905e705cd5d5f538e..63069adcc866e33fad7c6371e9ff06b0af797d73 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -173,7 +173,7 @@ void LLWearable::createVisualParams(LLAvatarAppearance *avatarp) { if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true)) { - LL_WARNS() << "could not link driven params for wearable " << getName() << " id: " << param->getID() << LL_ENDL; + LL_DEBUGS("Avatar") << "could not link driven params for wearable " << getName() << " id: " << param->getID() << LL_ENDL; continue; } } diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 2573417b260536371d7a93c87e459514b597db37..a17a5b0aa6bee291b535ffb0bc257ed10708cad7 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -91,12 +91,12 @@ target_link_libraries( # Add tests -if (LL_TESTS) - include(LLAddBuildTest) - # UNIT TESTS - SET(llcharacter_TEST_SOURCE_FILES - lljoint.cpp - ) - LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}") -endif (LL_TESTS) +#if (LL_TESTS) +# include(LLAddBuildTest) +# # UNIT TESTS +# SET(llcharacter_TEST_SOURCE_FILES +# lljoint.cpp +# ) +# LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}") +#endif (LL_TESTS) diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 0d558aeaa2be3717b5f34188d5e1ac2af755c297..e906d81ce15229ae99aad55dd06c4bcecee4d5c6 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -11,7 +11,7 @@ * 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, + * This library is distributed in the hope that it will be useful,7 * 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. @@ -29,6 +29,7 @@ #include "llbvhloader.h" #include <boost/tokenizer.hpp> +#include <boost/lexical_cast.hpp> #include "lldatapacker.h" #include "lldir.h" @@ -36,6 +37,7 @@ #include "llquantize.h" #include "llstl.h" #include "llapr.h" +#include "llsdserialize.h" using namespace std; @@ -121,52 +123,16 @@ LLQuaternion::Order bvhStringToOrder( char *str ) // LLBVHLoader() //----------------------------------------------------------------------------- -/* - LLBVHLoader::LLBVHLoader(const char* buffer) -{ - reset(); - - mStatus = loadTranslationTable("anim.ini"); - - if (mStatus == LLBVHLoader::ST_NO_XLT_FILE) - { - LL_WARNS() << "NOTE: No translation table found." << LL_ENDL; - return; - } - else - { - if (mStatus != LLBVHLoader::ST_OK) - { - LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - return; - } - } - - char error_text[128]; // Flawfinder: ignore - S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); - if (mStatus != LLBVHLoader::ST_OK) - { - LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - return; - } - - applyTranslations(); - optimize(); - - mInitialized = TRUE; -} -*/ -LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine) +LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ) { reset(); errorLine = 0; mStatus = loadTranslationTable("anim.ini"); loadStatus = mStatus; - LL_INFOS()<<"Load Status 00 : "<< loadStatus << LL_ENDL; + LL_INFOS("BVH") << "Load Status 00 : " << loadStatus << LL_ENDL; if (mStatus == E_ST_NO_XLT_FILE) { - //LL_WARNS() << "NOTE: No translation table found." << LL_ENDL; + LL_WARNS("BVH") << "NOTE: No translation table found." << LL_ENDL; loadStatus = mStatus; return; } @@ -174,28 +140,43 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error { if (mStatus != E_ST_OK) { - //LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; + LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; errorLine = getLineNumber(); loadStatus = mStatus; return; } } + + // Recognize all names we've been told are legal. + std::map<std::string, std::string>::iterator iter; + for (iter = joint_alias_map.begin(); iter != joint_alias_map.end(); iter++) + { + makeTranslation( iter->first , iter->second ); + } char error_text[128]; /* Flawfinder: ignore */ S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); + mStatus = loadBVHFile(buffer, error_text, error_line); //Reads all joints in BVH file. + + LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; + LL_DEBUGS("BVH") << "Raw data from file" << LL_ENDL; + dumpBVHInfo(); if (mStatus != E_ST_OK) { - //LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; + LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; loadStatus = mStatus; errorLine = getLineNumber(); return; } - applyTranslations(); + applyTranslations(); //Maps between joints found in file and the aliased names. optimize(); + LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; + LL_DEBUGS("BVH") << "After translations and optimize" << LL_ENDL; + dumpBVHInfo(); + mInitialized = TRUE; } @@ -211,10 +192,6 @@ LLBVHLoader::~LLBVHLoader() //------------------------------------------------------------------------ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) { - mLineNumber = 0; - mTranslations.clear(); - mConstraints.clear(); - //-------------------------------------------------------------------- // open file //-------------------------------------------------------------------- @@ -226,7 +203,7 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) if (!fp) return E_ST_NO_XLT_FILE; - LL_INFOS() << "NOTE: Loading translation table: " << fileName << LL_ENDL; + LL_INFOS("BVH") << "NOTE: Loading translation table: " << fileName << LL_ENDL; //-------------------------------------------------------------------- // register file to be closed on function exit @@ -244,7 +221,6 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) // load data one line at a time //-------------------------------------------------------------------- BOOL loadingGlobals = FALSE; - Translation *trans = NULL; while ( getLine(fp) ) { //---------------------------------------------------------------- @@ -271,13 +247,6 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) loadingGlobals = TRUE; continue; } - else - { - loadingGlobals = FALSE; - Translation &newTrans = mTranslations[ name ]; - trans = &newTrans; - continue; - } } //---------------------------------------------------------------- @@ -499,174 +468,102 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) mConstraints.push_back(constraint); continue; } + } + infile.close() ; + return E_ST_OK; +} +void LLBVHLoader::makeTranslation(std::string alias_name, std::string joint_name) +{ + //Translation &newTrans = (foomap.insert(value_type(alias_name, Translation()))).first(); + Translation &newTrans = mTranslations[ alias_name ]; //Uses []'s implicit call to ctor. + + newTrans.mOutName = joint_name; + LLMatrix3 fm; + LLVector3 vect1(0, 1, 0); + LLVector3 vect2(0, 0, 1); + LLVector3 vect3(1, 0, 0); + fm.setRows(vect1, vect2, vect3); + + newTrans.mFrameMatrix = fm; + +if (joint_name == "mPelvis") + { + newTrans.mRelativePositionKey = TRUE; + newTrans.mRelativeRotationKey = TRUE; + } - //---------------------------------------------------------------- - // at this point there must be a valid trans pointer - //---------------------------------------------------------------- - if ( ! trans ) - return E_ST_NO_XLT_NAME; - - //---------------------------------------------------------------- - // check for ignore flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "ignore")==0 ) - { - char trueFalse[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_IGNORE; - - trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); - continue; - } - - //---------------------------------------------------------------- - // check for relativepos flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "relativepos")==0 ) - { - F32 x, y, z; - char relpos[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %f %f", &x, &y, &z) == 3 ) - { - trans->mRelativePosition.setVec( x, y, z ); - } - else if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ - { - if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) - { - trans->mRelativePositionKey = TRUE; - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - - continue; - } - - //---------------------------------------------------------------- - // check for relativerot flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "relativerot")==0 ) - { - //F32 x, y, z; - char relpos[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ - { - if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) - { - trans->mRelativeRotationKey = TRUE; - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - - continue; - } - - //---------------------------------------------------------------- - // check for outname value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "outname")==0 ) - { - char outName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_OUTNAME; - - trans->mOutName = outName; - continue; - } - - //---------------------------------------------------------------- - // check for frame matrix value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "frame")==0 ) - { - LLMatrix3 fm; - if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", - &fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2], - &fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2], - &fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 ) - return E_ST_NO_XLT_MATRIX; - - trans->mFrameMatrix = fm; - continue; - } - - //---------------------------------------------------------------- - // check for offset matrix value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "offset")==0 ) - { - LLMatrix3 om; - if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", - &om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2], - &om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2], - &om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 ) - return E_ST_NO_XLT_MATRIX; - - trans->mOffsetMatrix = om; - continue; - } - - //---------------------------------------------------------------- - // check for mergeparent value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "mergeparent")==0 ) - { - char mergeParentName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_MERGEPARENT; - - trans->mMergeParentName = mergeParentName; - continue; - } - - //---------------------------------------------------------------- - // check for mergechild value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "mergechild")==0 ) - { - char mergeChildName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_MERGECHILD; +} - trans->mMergeChildName = mergeChildName; - continue; - } +ELoadStatus LLBVHLoader::loadAliases(const char * filename) +{ + LLSD aliases_sd; + + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,filename); + + llifstream input_stream; + input_stream.open(fullpath.c_str(), std::ios::in | std::ios::binary); + + if(input_stream.is_open()) + { + if ( LLSDSerialize::fromXML(aliases_sd, input_stream) ) + { + for(LLSD::map_iterator alias_iter = aliases_sd.beginMap(); + alias_iter != aliases_sd.endMap(); + ++alias_iter) + { + LLSD::String alias_name = alias_iter->first; + LLSD::String joint_name = alias_iter->second; + makeTranslation(alias_name, joint_name); + + } + } + else + { + return E_ST_NO_XLT_HEADER; + } + input_stream.close(); + } + else + { + LL_WARNS("BVH") << "Can't open joint alias file " << fullpath << LL_ENDL; + return E_ST_NO_XLT_FILE; + } + + return E_ST_OK; +} - //---------------------------------------------------------------- - // check for per-joint priority - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "priority")==0 ) +void LLBVHLoader::dumpBVHInfo() +{ + for (U32 j=0; j<mJoints.size(); j++) + { + Joint *joint = mJoints[j]; + LL_DEBUGS("BVH") << joint->mName << LL_ENDL; + for (S32 i=0; i<mNumFrames; i++) { - S32 priority; - if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return E_ST_NO_XLT_PRIORITY; - - trans->mPriorityModifier = priority; - continue; + if (i<joint->mKeys.size()) // Check this in case file load failed. + { + Key &prevkey = joint->mKeys[llmax(i-1,0)]; + Key &key = joint->mKeys[i]; + if ((i==0) || + (key.mPos[0] != prevkey.mPos[0]) || + (key.mPos[1] != prevkey.mPos[1]) || + (key.mPos[2] != prevkey.mPos[2]) || + (key.mRot[0] != prevkey.mRot[0]) || + (key.mRot[1] != prevkey.mRot[1]) || + (key.mRot[2] != prevkey.mRot[2]) + ) + { + LL_DEBUGS("BVH") << "FRAME " << i + << " POS " << key.mPos[0] << "," << key.mPos[1] << "," << key.mPos[2] + << " ROT " << key.mRot[0] << "," << key.mRot[1] << "," << key.mRot[2] << LL_ENDL; + } + } } - } - infile.close() ; - return E_ST_OK; } - //------------------------------------------------------------------------ // LLBVHLoader::loadBVHFile() //------------------------------------------------------------------------ @@ -746,6 +643,7 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & { iter++; // { iter++; // OFFSET + iter++; // } S32 depth = 0; for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) { @@ -777,12 +675,19 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & //--------------------------------------------------------------- // we require the root joint be "hip" - DEV-26188 //--------------------------------------------------------------- - const char* FORCED_ROOT_NAME = "hip"; - if ( (mJoints.size() == 0 ) && ( !strstr(jointName, FORCED_ROOT_NAME) ) ) - { - strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return E_ST_BAD_ROOT; - } + if (mJoints.size() == 0 ) + { + //The root joint of the BVH file must be hip (mPelvis) or an alias of mPelvis. + const char* FORCED_ROOT_NAME = "hip"; + + TranslationMap::iterator hip_joint = mTranslations.find( FORCED_ROOT_NAME ); + TranslationMap::iterator root_joint = mTranslations.find( jointName ); + if ( hip_joint == mTranslations.end() || root_joint == mTranslations.end() || root_joint->second.mOutName != hip_joint->second.mOutName ) + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_BAD_ROOT; + } + } //---------------------------------------------------------------- @@ -790,11 +695,14 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & //---------------------------------------------------------------- mJoints.push_back( new Joint( jointName ) ); Joint *joint = mJoints.back(); + LL_DEBUGS("BVH") << "Created joint " << jointName << LL_ENDL; + LL_DEBUGS("BVH") << "- index " << mJoints.size()-1 << LL_ENDL; S32 depth = 1; for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) { Joint *pjoint = mJoints[parent_joints[j]]; + LL_DEBUGS("BVH") << "- ancestor " << pjoint->mName << LL_ENDL; if (depth > pjoint->mChildTreeMaxDepth) { pjoint->mChildTreeMaxDepth = depth; @@ -863,6 +771,21 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & return E_ST_NO_CHANNELS; } + // Animating position (via mNumChannels = 6) is only supported for mPelvis. + int res = sscanf(line.c_str(), " CHANNELS %d", &joint->mNumChannels); + if ( res != 1 ) + { + // Assume default if not otherwise specified. + if (mJoints.size()==1) + { + joint->mNumChannels = 6; + } + else + { + joint->mNumChannels = 3; + } + } + //---------------------------------------------------------------- // get rotation order //---------------------------------------------------------------- @@ -961,57 +884,49 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & line = (*(iter++)); err_line++; - // read and store values - const char *p = line.c_str(); + // Split line into a collection of floats. + std::deque<F32> floats; + boost::char_separator<char> whitespace_sep("\t "); + tokenizer float_tokens(line, whitespace_sep); + tokenizer::iterator float_token_iter = float_tokens.begin(); + while (float_token_iter != float_tokens.end()) + { + try + { + F32 val = boost::lexical_cast<float>(*float_token_iter); + floats.push_back(val); + } + catch (const boost::bad_lexical_cast&) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_POS; + } + float_token_iter++; + } + LL_DEBUGS("BVH") << "Got " << floats.size() << " floats " << LL_ENDL; for (U32 j=0; j<mJoints.size(); j++) { Joint *joint = mJoints[j]; joint->mKeys.push_back( Key() ); Key &key = joint->mKeys.back(); - // get 3 pos values for root joint only - if (j==0) + if (floats.size() < joint->mNumChannels) { - if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_POS; - } + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_POS; } - // skip to next 3 values in the line - p = find_next_whitespace(p); - if (!p) + // assume either numChannels == 6, in which case we have pos + rot, + // or numChannels == 3, in which case we have only rot. + if (joint->mNumChannels == 6) { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; + key.mPos[0] = floats.front(); floats.pop_front(); + key.mPos[1] = floats.front(); floats.pop_front(); + key.mPos[2] = floats.front(); floats.pop_front(); } - p = find_next_whitespace(++p); - if (!p) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; - } - p = find_next_whitespace(++p); - if (!p) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; - } - - // get 3 rot values for joint - F32 rot[3]; - if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; - } - - p++; - - key.mRot[ joint->mOrder[0]-'X' ] = rot[0]; - key.mRot[ joint->mOrder[1]-'X' ] = rot[1]; - key.mRot[ joint->mOrder[2]-'X' ] = rot[2]; + key.mRot[ joint->mOrder[0]-'X' ] = floats.front(); floats.pop_front(); + key.mRot[ joint->mOrder[1]-'X' ] = floats.front(); floats.pop_front(); + key.mRot[ joint->mOrder[2]-'X' ] = floats.front(); floats.pop_front(); } } @@ -1045,7 +960,7 @@ void LLBVHLoader::applyTranslations() //---------------------------------------------------------------- if ( trans.mIgnore ) { - //LL_INFOS() << "NOTE: Ignoring " << joint->mName.c_str() << LL_ENDL; + //LL_INFOS() << "NOTE: Ignoring " << joint->mName.c_str() << LL_ENDL; joint->mIgnore = TRUE; continue; } @@ -1059,13 +974,12 @@ void LLBVHLoader::applyTranslations() joint->mOutName = trans.mOutName; } - //---------------------------------------------------------------- - // Set the ignorepos flag if necessary - //---------------------------------------------------------------- - if ( joint->mOutName == std::string("mPelvis") ) - { - joint->mIgnorePositions = FALSE; - } + //Allow joint position changes as of SL-318 + joint->mIgnorePositions = FALSE; + if (joint->mNumChannels == 3) + { + joint->mIgnorePositions = TRUE; + } //---------------------------------------------------------------- // Set the relativepos flags if necessary @@ -1334,6 +1248,9 @@ void LLBVHLoader::reset() mInitialized = FALSE; mEmoteName = ""; + mLineNumber = 0; + mTranslations.clear(); + mConstraints.clear(); } //------------------------------------------------------------------------ @@ -1508,8 +1425,8 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) frame++; } - // output position keys (only for 1st joint) - if ( ji == mJoints.begin() && !joint->mIgnorePositions ) + // output position keys if joint has motion. + if ( !joint->mIgnorePositions ) { dp.packS32(joint->mNumPosKeys, "num_pos_keys"); @@ -1539,6 +1456,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) outPos *= INCHES_TO_METERS; + //SL-318 Pelvis position can only move 5m. Limiting all joint position offsets to this dist. outPos -= relPos; outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); @@ -1586,5 +1504,6 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop"); } + return TRUE; } diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index f816b7627723bca0d18cedd545099a88835c34e5..47fe4090472bb4da83702239725a40909026bba6 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -102,6 +102,7 @@ struct Joint mNumRotKeys = 0; mChildTreeMaxDepth = 0; mPriority = 0; + mNumChannels = 3; } // Include aligned members first @@ -123,6 +124,7 @@ struct Joint S32 mNumRotKeys; S32 mChildTreeMaxDepth; S32 mPriority; + S32 mNumChannels; }; @@ -225,8 +227,7 @@ class LLBVHLoader friend class LLKeyframeMotion; public: // Constructor -// LLBVHLoader(const char* buffer); - LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine); + LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ); ~LLBVHLoader(); /* @@ -265,13 +266,22 @@ class LLBVHLoader static const char *ST_NO_XLT_EMOTE; static const char *ST_BAD_ROOT; */ + // Loads the specified translation table. ELoadStatus loadTranslationTable(const char *fileName); + //Create a new joint alias + void makeTranslation(std::string key, std::string value); + + // Loads joint aliases from XML file. + ELoadStatus loadAliases(const char * filename); + // Load the specified BVH file. // Returns status code. ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line); + void dumpBVHInfo(); + // Applies translations to BVH data loaded. void applyTranslations(); diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index f4a37a139aa147e00fee9ee9e8ac64c492cd35b2..ddf89f30f22bb34f35df1ed65775c0ab39dd56d1 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -117,6 +117,7 @@ LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *characte addJointState( mWristState ); // propagate joint positions to kinematic chain + // SL-315 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); @@ -143,6 +144,7 @@ LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *characte BOOL LLEditingMotion::onActivate() { // propagate joint positions to kinematic chain + // SL-315 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); @@ -181,6 +183,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) focus_pt += mCharacter->getCharacterPosition(); // propagate joint positions to kinematic chain + // SL-315 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); @@ -217,7 +220,8 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) " and focus point " << focus_pt << LL_ENDL; target.setVec(1.f, 1.f, 1.f); } - + + // SL-315 mTarget.setPosition( target + mParentJoint.getPosition()); // LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 812c4201af465815b3e3442c59f0bc7982aaf9f6..e91de7a11d8a17a3e73942957a5ac4342f9f1b17 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -285,7 +285,10 @@ LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id) mName = "eye_rot"; mLeftEyeState = new LLJointState; + mAltLeftEyeState = new LLJointState; + mRightEyeState = new LLJointState; + mAltRightEyeState = new LLJointState; } @@ -318,18 +321,38 @@ LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character) return STATUS_FAILURE; } + mAltLeftEyeState->setJoint( character->getJoint("mFaceEyeAltLeft") ); + if ( ! mAltLeftEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get alt left eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + mRightEyeState->setJoint( character->getJoint("mEyeRight") ); if ( ! mRightEyeState->getJoint() ) { - LL_INFOS() << getName() << ": Can't get Right eyeball joint." << LL_ENDL; + LL_INFOS() << getName() << ": Can't get right eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mAltRightEyeState->setJoint( character->getJoint("mFaceEyeAltRight") ); + if ( ! mAltRightEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get alt right eyeball joint." << LL_ENDL; return STATUS_FAILURE; } mLeftEyeState->setUsage(LLJointState::ROT); + mAltLeftEyeState->setUsage(LLJointState::ROT); + mRightEyeState->setUsage(LLJointState::ROT); + mAltRightEyeState->setUsage(LLJointState::ROT); addJointState( mLeftEyeState ); + addJointState( mAltLeftEyeState ); + addJointState( mRightEyeState ); + addJointState( mAltRightEyeState ); return STATUS_SUCCESS; } @@ -343,17 +366,98 @@ BOOL LLEyeMotion::onActivate() return TRUE; } - //----------------------------------------------------------------------------- -// LLEyeMotion::onUpdate() +// LLEyeMotion::adjustEyeTarget() //----------------------------------------------------------------------------- -BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) +void LLEyeMotion::adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_state, LLJointState& right_eye_state) { // Compute eye rotation. + BOOL has_eye_target = FALSE; LLQuaternion target_eye_rot; LLVector3 eye_look_at; F32 vergence; + if (targetPos) + { + LLVector3 skyward(0.f, 0.f, 1.f); + LLVector3 left; + LLVector3 up; + + eye_look_at = *targetPos; + has_eye_target = TRUE; + F32 lookAtDistance = eye_look_at.normVec(); + + left.setVec(skyward % eye_look_at); + up.setVec(eye_look_at % left); + + target_eye_rot = LLQuaternion(eye_look_at, left, up); + // convert target rotation to head-local coordinates + target_eye_rot *= ~mHeadJoint->getWorldRotation(); + // eliminate any Euler roll - we're lucky that roll is applied last. + F32 roll, pitch, yaw; + target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); + target_eye_rot.setQuat(0.0f, pitch, yaw); + // constrain target orientation to be in front of avatar's face + target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); + + // calculate vergence + F32 interocular_dist = (left_eye_state.getJoint()->getWorldPosition() - right_eye_state.getJoint()->getWorldPosition()).magVec(); + vergence = -atan2((interocular_dist / 2.f), lookAtDistance); + llclamp(vergence, -F_PI_BY_TWO, 0.f); + } + else + { + target_eye_rot = LLQuaternion::DEFAULT; + vergence = 0.f; + } + + //RN: subtract 4 degrees to account for foveal angular offset relative to pupil + vergence += 4.f * DEG_TO_RAD; + + // calculate eye jitter + LLQuaternion eye_jitter_rot; + + // vergence not too high... + if (vergence > -0.05f) + { + //...go ahead and jitter + eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); + } + else + { + //...or don't + eye_jitter_rot.loadIdentity(); + } + + // calculate vergence of eyes as an object gets closer to the avatar's head + LLQuaternion vergence_quat; + + if (has_eye_target) + { + vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); + } + else + { + vergence_quat.loadIdentity(); + } + + // calculate eye rotations + LLQuaternion left_eye_rot = target_eye_rot; + left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; + + LLQuaternion right_eye_rot = target_eye_rot; + vergence_quat.transQuat(); + right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; + + left_eye_state.setRotation( left_eye_rot ); + right_eye_state.setRotation( right_eye_rot ); +} + +//----------------------------------------------------------------------------- +// LLEyeMotion::onUpdate() +//----------------------------------------------------------------------------- +BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) +{ //calculate jitter if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime) { @@ -426,83 +530,10 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) } } - BOOL has_eye_target = FALSE; LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); - if (targetPos) - { - LLVector3 skyward(0.f, 0.f, 1.f); - LLVector3 left; - LLVector3 up; - - eye_look_at = *targetPos; - has_eye_target = TRUE; - F32 lookAtDistance = eye_look_at.normVec(); - - left.setVec(skyward % eye_look_at); - up.setVec(eye_look_at % left); - - target_eye_rot = LLQuaternion(eye_look_at, left, up); - // convert target rotation to head-local coordinates - target_eye_rot *= ~mHeadJoint->getWorldRotation(); - // eliminate any Euler roll - we're lucky that roll is applied last. - F32 roll, pitch, yaw; - target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); - target_eye_rot.setQuat(0.0f, pitch, yaw); - // constrain target orientation to be in front of avatar's face - target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); - - // calculate vergence - F32 interocular_dist = (mLeftEyeState->getJoint()->getWorldPosition() - mRightEyeState->getJoint()->getWorldPosition()).magVec(); - vergence = -atan2((interocular_dist / 2.f), lookAtDistance); - llclamp(vergence, -F_PI_BY_TWO, 0.f); - } - else - { - target_eye_rot = LLQuaternion::DEFAULT; - vergence = 0.f; - } - - //RN: subtract 4 degrees to account for foveal angular offset relative to pupil - vergence += 4.f * DEG_TO_RAD; - - // calculate eye jitter - LLQuaternion eye_jitter_rot; - - // vergence not too high... - if (vergence > -0.05f) - { - //...go ahead and jitter - eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); - } - else - { - //...or don't - eye_jitter_rot.loadIdentity(); - } - - // calculate vergence of eyes as an object gets closer to the avatar's head - LLQuaternion vergence_quat; - - if (has_eye_target) - { - vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); - } - else - { - vergence_quat.loadIdentity(); - } - - // calculate eye rotations - LLQuaternion left_eye_rot = target_eye_rot; - left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; - - LLQuaternion right_eye_rot = target_eye_rot; - vergence_quat.transQuat(); - right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; - - mLeftEyeState->setRotation( left_eye_rot ); - mRightEyeState->setRotation( right_eye_rot ); + adjustEyeTarget(targetPos, *mLeftEyeState, *mRightEyeState); + adjustEyeTarget(targetPos, *mAltLeftEyeState, *mAltRightEyeState); return TRUE; } @@ -519,11 +550,23 @@ void LLEyeMotion::onDeactivate() joint->setRotation(LLQuaternion::DEFAULT); } + joint = mAltLeftEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } + joint = mRightEyeState->getJoint(); if (joint) { joint->setRotation(LLQuaternion::DEFAULT); } + + joint = mAltRightEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } } // End diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h index 569dbef2dd7b7be73ec4f5a8570ac60782752f0f..53ae1813bc1bb5d6a50c991d91a808b5a3fc5665 100644 --- a/indra/llcharacter/llheadrotmotion.h +++ b/indra/llcharacter/llheadrotmotion.h @@ -176,6 +176,8 @@ class LLEyeMotion : // it will be deactivated virtual BOOL onActivate(); + void adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_state, LLJointState& right_eye_state); + // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -193,6 +195,8 @@ class LLEyeMotion : LLJoint *mHeadJoint; LLPointer<LLJointState> mLeftEyeState; LLPointer<LLJointState> mRightEyeState; + LLPointer<LLJointState> mAltLeftEyeState; + LLPointer<LLJointState> mAltRightEyeState; LLFrameTimer mEyeJitterTimer; F32 mEyeJitterTime; diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 8fa08a2a6ce0ea7314e94973661c376164ec1eec..a3d5679f655a10eeab7395e9039ae386751fa195 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -32,6 +32,8 @@ #include "lljoint.h" #include "llmath.h" +#include "llcallstack.h" +#include <boost/algorithm/string.hpp> S32 LLJoint::sNumUpdates = 0; S32 LLJoint::sNumTouches = 0; @@ -42,7 +44,7 @@ bool attachment_map_iter_compare_key(const T& a, const T& b) return a.first < b.first; } -bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const +bool LLVector3OverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const { pos = LLVector3(0,0,0); mesh_id = LLUUID(); @@ -60,7 +62,7 @@ bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const return found; } -void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const +void LLVector3OverrideMap::showJointVector3Overrides( std::ostringstream& os ) const { map_type::const_iterator max_it = std::max_element(m_map.begin(), m_map.end(), @@ -73,23 +75,23 @@ void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const } } -U32 LLPosOverrideMap::count() const +U32 LLVector3OverrideMap::count() const { return m_map.size(); } -void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) +void LLVector3OverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) { m_map[mesh_id] = pos; } -bool LLPosOverrideMap::remove(const LLUUID& mesh_id) +bool LLVector3OverrideMap::remove(const LLUUID& mesh_id) { U32 remove_count = m_map.erase(mesh_id); return (remove_count > 0); } -void LLPosOverrideMap::clear() +void LLVector3OverrideMap::clear() { m_map.clear(); } @@ -108,6 +110,8 @@ void LLJoint::init() mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; mUpdateXform = TRUE; + mSupport = SUPPORT_BASE; + mEnd = LLVector3(0.0f, 0.0f, 0.0f); } LLJoint::LLJoint() : @@ -124,13 +128,12 @@ LLJoint::LLJoint(S32 joint_num) : touch(); } - //----------------------------------------------------------------------------- // LLJoint() // Class Constructor //----------------------------------------------------------------------------- LLJoint::LLJoint(const std::string &name, LLJoint *parent) : - mJointNum(0) + mJointNum(-2) { init(); mUpdateXform = FALSE; @@ -169,6 +172,27 @@ void LLJoint::setup(const std::string &name, LLJoint *parent) } } +//----------------------------------------------------------------------------- +// setSupport() +//----------------------------------------------------------------------------- +void LLJoint::setSupport(const std::string& support_name) +{ + if (support_name == "extended") + { + setSupport(SUPPORT_EXTENDED); + } + else if (support_name == "base") + { + setSupport(SUPPORT_BASE); + } + else + { + LL_WARNS() << "unknown support string " << support_name << LL_ENDL; + setSupport(SUPPORT_BASE); + } +} + + //----------------------------------------------------------------------------- // touch() // Sets all dirty flags for all children, recursively. @@ -194,6 +218,18 @@ void LLJoint::touch(U32 flags) } } +//----------------------------------------------------------------------------- +// setJointNum() +//----------------------------------------------------------------------------- +void LLJoint::setJointNum(S32 joint_num) +{ + mJointNum = joint_num; + if (mJointNum + 2 >= LL_CHARACTER_MAX_ANIMATED_JOINTS) + { + LL_INFOS() << "LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be increased" << LL_ENDL; + LL_ERRS() << "joint_num " << joint_num << " + 2 is too large for " << LL_CHARACTER_MAX_ANIMATED_JOINTS << LL_ENDL; + } +} //----------------------------------------------------------------------------- // getRoot() //----------------------------------------------------------------------------- @@ -290,43 +326,119 @@ const LLVector3& LLJoint::getPosition() bool do_debug_joint(const std::string& name) { - return false; + if (std::find(LLJoint::s_debugJointNames.begin(), LLJoint::s_debugJointNames.end(),name) != LLJoint::s_debugJointNames.end()) + { + return true; + } + return false; } //-------------------------------------------------------------------- // setPosition() //-------------------------------------------------------------------- -void LLJoint::setPosition( const LLVector3& pos ) +void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment_overrides ) { - if (pos != getPosition()) + LLVector3 pos(requested_pos); + + LLVector3 active_override; + LLUUID mesh_id; + if (apply_attachment_overrides && m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override)) + { + if (pos != active_override && do_debug_joint(getName())) + { + LLScopedContextString str("setPosition"); + LL_DEBUGS("Avatar") << " joint " << getName() << " requested_pos " << requested_pos + << " overriden by attachment " << active_override << LL_ENDL; + } + pos = active_override; + } + if ((pos != getPosition()) && do_debug_joint(getName())) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; - } + LLScopedContextString str("setPosition"); + LLCallStack cs; + LLContextStatus con_status; + LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; + LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << "====================" << LL_ENDL; + LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } - mXform.setPosition(pos); - touch(MATRIX_DIRTY | POSITION_DIRTY); + if (pos != getPosition()) + { + mXform.setPosition(pos); + touch(MATRIX_DIRTY | POSITION_DIRTY); + } +} + +void LLJoint::setDefaultPosition( const LLVector3& pos ) +{ + mDefaultPosition = pos; +} + +const LLVector3& LLJoint::getDefaultPosition() const +{ + return mDefaultPosition; +} + +void LLJoint::setDefaultScale( const LLVector3& scale ) +{ + mDefaultScale = scale; +} + +const LLVector3& LLJoint::getDefaultScale() const +{ + return mDefaultScale; } void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) { std::ostringstream os; os << joint.m_posBeforeOverrides; - joint.m_attachmentOverrides.showJointPosOverrides(os); + joint.m_attachmentPosOverrides.showJointVector3Overrides(os); + LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; +} + +void showJointScaleOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) +{ + std::ostringstream os; + os << joint.m_scaleBeforeOverrides; + joint.m_attachmentScaleOverrides.showJointVector3Overrides(os); LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; } +bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const +{ + LLVector3 diff = pos - getDefaultPosition(); + const F32 max_joint_pos_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset; +} + +bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const +{ + LLVector3 diff = scale - getDefaultScale(); + const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; +} + //-------------------------------------------------------------------- // addAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } - if (!m_attachmentOverrides.count()) + // BENTO + // Not clear pelvis overrides are meaningful/useful. + //if (mName == "mPelvis") + //{ + // return; + //} + + LLVector3 before_pos; + LLUUID before_mesh_id; + bool has_active_override_before = hasAttachmentPosOverride( before_pos, before_mesh_id ); + if (!m_attachmentPosOverrides.count()) { if (do_debug_joint(getName())) { @@ -334,32 +446,50 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh } m_posBeforeOverrides = getPosition(); } - m_attachmentOverrides.add(mesh_id,pos); - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; - } - updatePos(av_info); + m_attachmentPosOverrides.add(mesh_id,pos); + LLVector3 after_pos; + LLUUID after_mesh_id; + hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_before || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; + } + updatePos(av_info); + } } //-------------------------------------------------------------------- // removeAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } - if (m_attachmentOverrides.remove(mesh_id)) + LLVector3 before_pos; + LLUUID before_mesh_id; + hasAttachmentPosOverride( before_pos, before_mesh_id ); + if (m_attachmentPosOverrides.remove(mesh_id)) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() - << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; - showJointPosOverrides(*this, "remove", av_info); - } - updatePos(av_info); + LLVector3 after_pos; + LLUUID after_mesh_id; + bool has_active_override_after = hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_after || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; + showJointPosOverrides(*this, "remove", av_info); + } + updatePos(av_info); + } } } @@ -368,7 +498,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str //-------------------------------------------------------------------- bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const { - return m_attachmentOverrides.findActiveOverride(mesh_id,pos); + return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos); } //-------------------------------------------------------------------- @@ -376,11 +506,81 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const //-------------------------------------------------------------------- void LLJoint::clearAttachmentPosOverrides() { - if (m_attachmentOverrides.count()) + if (m_attachmentPosOverrides.count()) { - m_attachmentOverrides.clear(); + m_attachmentPosOverrides.clear(); setPosition(m_posBeforeOverrides); - setId( LLUUID::null ); + } +} + +//-------------------------------------------------------------------- +// getAllAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides, + std::set<LLVector3>& distinct_pos_overrides) +{ + num_pos_overrides = m_attachmentPosOverrides.count(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + for (; it != m_attachmentPosOverrides.getMap().end(); ++it) + { + distinct_pos_overrides.insert(it->second); + } +} + +//-------------------------------------------------------------------- +// getAllAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::getAllAttachmentScaleOverrides(S32& num_scale_overrides, + std::set<LLVector3>& distinct_scale_overrides) +{ + num_scale_overrides = m_attachmentScaleOverrides.count(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) + { + distinct_scale_overrides.insert(it->second); + } +} + +//-------------------------------------------------------------------- +// showAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const +{ + LLVector3 active_override; + bool has_active_override; + LLUUID mesh_id; + has_active_override = m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override); + U32 count = m_attachmentPosOverrides.count(); + if (count==1) + { + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " has single attachment pos override " << highlight << "" << it->second << " default " << mDefaultPosition << LL_ENDL; + } + else if (count>1) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment pos overrides" << LL_ENDL; + std::set<LLVector3> distinct_offsets; + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + for (; it != m_attachmentPosOverrides.getMap().end(); ++it) + { + distinct_offsets.insert(it->second); + } + if (distinct_offsets.size()>1) + { + LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; + } + std::set<LLVector3>::iterator dit = distinct_offsets.begin(); + for ( ; dit != distinct_offsets.end(); ++dit) + { + std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; + LL_DEBUGS("Avatar") << " POS " << highlight << "" << (*dit) << " default " << mDefaultPosition << LL_ENDL; + } } } @@ -391,19 +591,177 @@ void LLJoint::updatePos(const std::string& av_info) { LLVector3 pos, found_pos; LLUUID mesh_id; - if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos)) + if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos)) { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentPosOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; + } pos = found_pos; } else { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + } pos = m_posBeforeOverrides; } setPosition(pos); } +//-------------------------------------------------------------------- +// updateScale() +//-------------------------------------------------------------------- +void LLJoint::updateScale(const std::string& av_info) +{ + LLVector3 scale, found_scale; + LLUUID mesh_id; + if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner of " << m_attachmentScaleOverrides.count() << " is mesh " << mesh_id << " scale " << found_scale << LL_ENDL; + } + scale = found_scale; + } + else + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner is scaleBeforeOverrides " << m_scaleBeforeOverrides << LL_ENDL; + } + scale = m_scaleBeforeOverrides; + } + setScale(scale); +} + +//-------------------------------------------------------------------- +// addAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ) +{ + if (mesh_id.isNull()) + { + return; + } + if (!m_attachmentScaleOverrides.count()) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL; + } + m_scaleBeforeOverrides = getScale(); + } + m_attachmentScaleOverrides.add(mesh_id,scale); + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL; + } + updateScale(av_info); +} + +//-------------------------------------------------------------------- +// removeAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ) +{ + if (mesh_id.isNull()) + { + return; + } + if (m_attachmentScaleOverrides.remove(mesh_id)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL; + showJointScaleOverrides(*this, "remove", av_info); + } + updateScale(av_info); + } +} + +//-------------------------------------------------------------------- + // hasAttachmentScaleOverride() + //-------------------------------------------------------------------- +bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const +{ + return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale); +} + +//-------------------------------------------------------------------- +// clearAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::clearAttachmentScaleOverrides() +{ + if (m_attachmentScaleOverrides.count()) + { + m_attachmentScaleOverrides.clear(); + setScale(m_scaleBeforeOverrides); + } +} + +//-------------------------------------------------------------------- +// showAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const +{ + LLVector3 active_override; + bool has_active_override; + LLUUID mesh_id; + has_active_override = m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override); + U32 count = m_attachmentScaleOverrides.count(); + if (count==1) + { + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " has single attachment scale override " << highlight << "" << it->second << " default " << mDefaultScale << LL_ENDL; + } + else if (count>1) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment scale overrides" << LL_ENDL; + std::set<LLVector3> distinct_offsets; + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) + { + distinct_offsets.insert(it->second); + } + if (distinct_offsets.size()>1) + { + LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; + } + std::set<LLVector3>::iterator dit = distinct_offsets.begin(); + for ( ; dit != distinct_offsets.end(); ++dit) + { + std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; + LL_DEBUGS("Avatar") << " POS " << highlight << "" << (*dit) << " default " << mDefaultScale << LL_ENDL; + } + } +} + +// init static +LLJoint::debug_joint_name_t LLJoint::s_debugJointNames = debug_joint_name_t(); + +//-------------------------------------------------------------------- +// setDebugJointNames +//-------------------------------------------------------------------- +void LLJoint::setDebugJointNames(const debug_joint_name_t& names) +{ + s_debugJointNames = names; +} +void LLJoint::setDebugJointNames(const std::string& names_string) +{ + debug_joint_name_t names; + boost::split(names, names_string, boost::is_any_of(" :,")); + setDebugJointNames(names); +} + //-------------------------------------------------------------------- // getWorldPosition() //-------------------------------------------------------------------- @@ -529,13 +887,32 @@ const LLVector3& LLJoint::getScale() //-------------------------------------------------------------------- // setScale() //-------------------------------------------------------------------- -void LLJoint::setScale( const LLVector3& scale ) +void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_overrides ) { -// if (mXform.getScale() != scale) + LLVector3 scale(requested_scale); + LLUUID mesh_id; + LLVector3 active_override; + if (apply_attachment_overrides && m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override)) + { + if (scale != active_override && do_debug_joint(getName())) + { + LLScopedContextString str("setScale"); + LL_DEBUGS("Avatar") << " joint " << getName() << " requested_scale " << requested_scale + << " overriden by attachment " << active_override << LL_ENDL; + } + scale = active_override; + } + if ((mXform.getScale() != scale) && do_debug_joint(getName())) { - mXform.setScale(scale); - touch(); + LLScopedContextString str("setScale"); + LLCallStack cs; + LLContextStatus con_status; + LL_DEBUGS("Avatar") << " joint " << getName() << " set scale " << scale << LL_ENDL; + LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << LL_ENDL; + LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } + mXform.setScale(scale); + touch(); } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 2abe1d6db1510cb6da94adf987e473a271c6da73..0c8fbfebb0e0c737e3012d1439ee683eff38812d 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -40,24 +40,33 @@ #include "xform.h" const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; -const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4! -const U32 LL_HAND_JOINT_NUM = 31; -const U32 LL_FACE_JOINT_NUM = 30; +// Need to set this to count of animate-able joints, +// currently = #bones + #collision_volumes + #attachments + 2, +// rounded to next multiple of 4. +const U32 LL_CHARACTER_MAX_ANIMATED_JOINTS = 216; // must be divisible by 4! +const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 110; + +// These should be higher than the joint_num of any +// other joint, to avoid conflicts in updateMotionsByType() +const U32 LL_HAND_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-1); +const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-2); const S32 LL_CHARACTER_MAX_PRIORITY = 7; const F32 LL_MAX_PELVIS_OFFSET = 5.f; -class LLPosOverrideMap +class LLVector3OverrideMap { public: - LLPosOverrideMap() {} + LLVector3OverrideMap() {} bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const; - void showJointPosOverrides(std::ostringstream& os) const; + void showJointVector3Overrides(std::ostringstream& os) const; U32 count() const; void add(const LLUUID& mesh_id, const LLVector3& pos); bool remove(const LLUUID& mesh_id); void clear(); -private: + typedef std::map<LLUUID,LLVector3> map_type; + const map_type& getMap() const { return m_map; } +private: map_type m_map; }; @@ -86,17 +95,26 @@ class LLJoint POSITION_DIRTY = 0x1 << 2, ALL_DIRTY = 0x7 }; +public: + enum SupportCategory + { + SUPPORT_BASE, + SUPPORT_EXTENDED + }; protected: std::string mName; + SupportCategory mSupport; + // parent joint LLJoint *mParent; // explicit transformation members LLXformMatrix mXform; - LLUUID mId; - + LLVector3 mDefaultPosition; + LLVector3 mDefaultScale; + public: U32 mDirtyFlags; BOOL mUpdateXform; @@ -104,6 +122,10 @@ class LLJoint // describes the skin binding pose LLVector3 mSkinOffset; + // Endpoint of the bone, if applicable. This is only relevant for + // external programs like Blender, and for diagnostic display. + LLVector3 mEnd; + S32 mJointNum; // child joints @@ -113,15 +135,40 @@ class LLJoint // debug statics static S32 sNumTouches; static S32 sNumUpdates; + typedef std::set<std::string> debug_joint_name_t; + static debug_joint_name_t s_debugJointNames; + static void setDebugJointNames(const debug_joint_name_t& names); + static void setDebugJointNames(const std::string& names_string); - LLPosOverrideMap m_attachmentOverrides; + // Position overrides + LLVector3OverrideMap m_attachmentPosOverrides; LLVector3 m_posBeforeOverrides; + // Scale overrides + LLVector3OverrideMap m_attachmentScaleOverrides; + LLVector3 m_scaleBeforeOverrides; + void updatePos(const std::string& av_info); + void updateScale(const std::string& av_info); public: LLJoint(); - LLJoint(S32 joint_num); + + // Note: these joint_num constructors are a bad idea because there + // are only a couple of places in the code where it is useful to + // have a joint num for a joint (for joints that are used in + // animations), and including them as part of the constructor then + // forces us to maintain an alternate path through the entire + // large-ish class hierarchy of joint types. The only reason they + // are still here now is to avoid breaking the baking service + // (appearanceutility) builds; these constructors are not used in + // the viewer. Once the appearance utility is updated to remove + // these joint num references, which it shouldn't ever need, from + // its own classes, we can also remove all the joint_num + // constructors from LLJoint, LLViewerJoint, LLAvatarJoint, and + // createAvatarJoint. + LLJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* LLJoint( const std::string &name, LLJoint *parent=NULL ); virtual ~LLJoint(); @@ -139,6 +186,19 @@ class LLJoint const std::string& getName() const { return mName; } void setName( const std::string &name ) { mName = name; } + // joint num + S32 getJointNum() const { return mJointNum; } + void setJointNum(S32 joint_num); + + // get/set support + SupportCategory getSupport() const { return mSupport; } + void setSupport( const SupportCategory& support) { mSupport = support; } + void setSupport( const std::string& support_string); + + // get/set end point + void setEnd( const LLVector3& end) { mEnd = end; } + const LLVector3& getEnd() const { return mEnd; } + // getParent LLJoint *getParent() { return mParent; } @@ -155,10 +215,16 @@ class LLJoint // get/set local position const LLVector3& getPosition(); - void setPosition( const LLVector3& pos ); - + void setPosition( const LLVector3& pos, bool apply_attachment_overrides = false ); + + // Tracks the default position defined by the skeleton void setDefaultPosition( const LLVector3& pos ); - + const LLVector3& getDefaultPosition() const; + + // Tracks the default scale defined by the skeleton + void setDefaultScale( const LLVector3& scale ); + const LLVector3& getDefaultScale() const; + // get/set world position LLVector3 getWorldPosition(); LLVector3 getLastWorldPosition(); @@ -175,7 +241,7 @@ class LLJoint // get/set local scale const LLVector3& getScale(); - void setScale( const LLVector3& scale ); + void setScale( const LLVector3& scale, bool apply_attachment_overrides = false ); // get/set world matrix const LLMatrix4 &getWorldMatrix(); @@ -198,17 +264,26 @@ class LLJoint virtual BOOL isAnimatable() const { return TRUE; } - S32 getJointNum() const { return mJointNum; } - - void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ); - void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ); + void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); + void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const; void clearAttachmentPosOverrides(); - - //Accessor for the joint id - LLUUID getId( void ) { return mId; } - //Setter for the joints id - void setId( const LLUUID& id ) { mId = id;} + void showAttachmentPosOverrides(const std::string& av_info) const; + + void addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ); + void removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ); + bool hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const; + void clearAttachmentScaleOverrides(); + void showAttachmentScaleOverrides(const std::string& av_info) const; + + void getAllAttachmentPosOverrides(S32& num_pos_overrides, + std::set<LLVector3>& distinct_pos_overrides); + void getAllAttachmentScaleOverrides(S32& num_scale_overrides, + std::set<LLVector3>& distinct_scale_overrides); + + // These are used in checks of whether a pos/scale override is considered significant. + bool aboveJointPosThreshold(const LLVector3& pos) const; + bool aboveJointScaleThreshold(const LLVector3& scale) const; }; #endif // LL_LLJOINT_H diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index e786dfff8691432e246034f6b4e4be8b1b9fa574..89f34a92c84f4a362793f09165bc9d01161cb0e2 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -498,6 +498,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact // request asset mAssetStatus = ASSET_FETCHED; + LL_DEBUGS("Animation") << "Requesting data fetch for: " << mID << LL_ENDL; character_id = new LLUUID(mCharacter->getID()); gAssetStorage->getAssetData(mID, LLAssetType::AT_ANIMATION, @@ -1380,7 +1381,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) LL_WARNS() << "no joints in animation" << LL_ENDL; return FALSE; } - else if (num_motions > LL_CHARACTER_MAX_JOINTS) + else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS) { LL_WARNS() << "too many joints in animation" << LL_ENDL; return FALSE; @@ -1419,7 +1420,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) LLJoint *joint = mCharacter->getJoint( joint_name ); if (joint) { + S32 joint_num = joint->getJointNum(); // LL_INFOS() << " joint: " << joint_name << LL_ENDL; + if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) + { + LL_WARNS() << "Joint will be omitted from animation: joint_num " << joint_num << " is outside of legal range [0-" + << LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << joint->getName() << LL_ENDL; + joint = NULL; + } } else { @@ -1603,6 +1611,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (old_version) { success = dp.unpackVector3(pos_key.mPosition, "pos"); + + //MAINT-6162 + pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VY] = llclamp( pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VZ] = llclamp( pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + } else { @@ -1868,6 +1882,8 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const { BOOL success = TRUE; + LL_DEBUGS("BVH") << "serializing" << LL_ENDL; + success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version"); success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority"); @@ -1881,6 +1897,19 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose"); success &= dp.packU32(mJointMotionList->getNumJointMotions(), "num_joints"); + LL_DEBUGS("BVH") << "version " << KEYFRAME_MOTION_VERSION << LL_ENDL; + LL_DEBUGS("BVH") << "sub_version " << KEYFRAME_MOTION_SUBVERSION << LL_ENDL; + LL_DEBUGS("BVH") << "base_priority " << mJointMotionList->mBasePriority << LL_ENDL; + LL_DEBUGS("BVH") << "duration " << mJointMotionList->mDuration << LL_ENDL; + LL_DEBUGS("BVH") << "emote_name " << mJointMotionList->mEmoteName << LL_ENDL; + LL_DEBUGS("BVH") << "loop_in_point " << mJointMotionList->mLoopInPoint << LL_ENDL; + LL_DEBUGS("BVH") << "loop_out_point " << mJointMotionList->mLoopOutPoint << LL_ENDL; + LL_DEBUGS("BVH") << "loop " << mJointMotionList->mLoop << LL_ENDL; + LL_DEBUGS("BVH") << "ease_in_duration " << mJointMotionList->mEaseInDuration << LL_ENDL; + LL_DEBUGS("BVH") << "ease_out_duration " << mJointMotionList->mEaseOutDuration << LL_ENDL; + LL_DEBUGS("BVH") << "hand_pose " << mJointMotionList->mHandPose << LL_ENDL; + LL_DEBUGS("BVH") << "num_joints " << mJointMotionList->getNumJointMotions() << LL_ENDL; + for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) { JointMotion* joint_motionp = mJointMotionList->getJointMotion(i); @@ -1888,6 +1917,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys"); + LL_DEBUGS("BVH") << "Joint " << joint_motionp->mJointName << LL_ENDL; for (RotationCurve::key_map_t::iterator iter = joint_motionp->mRotationCurve.mKeys.begin(); iter != joint_motionp->mRotationCurve.mKeys.end(); ++iter) { @@ -1905,6 +1935,8 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU16(x, "rot_angle_x"); success &= dp.packU16(y, "rot_angle_y"); success &= dp.packU16(z, "rot_angle_z"); + + LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL; } success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys"); @@ -1923,37 +1955,54 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU16(x, "pos_x"); success &= dp.packU16(y, "pos_y"); success &= dp.packU16(z, "pos_z"); + + LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mPosition.mV[VX] <<","<< pos_key.mPosition.mV[VY] <<","<< pos_key.mPosition.mV[VZ] << LL_ENDL; } } success &= dp.packS32(mJointMotionList->mConstraints.size(), "num_constraints"); + LL_DEBUGS("BVH") << "num_constraints " << mJointMotionList->mConstraints.size() << LL_ENDL; for (JointMotionList::constraint_list_t::const_iterator iter = mJointMotionList->mConstraints.begin(); iter != mJointMotionList->mConstraints.end(); ++iter) { JointConstraintSharedData* shared_constraintp = *iter; success &= dp.packU8(shared_constraintp->mChainLength, "chain_length"); success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type"); - char volume_name[16]; /* Flawfinder: ignore */ - snprintf(volume_name, sizeof(volume_name), "%s", /* Flawfinder: ignore */ + char source_volume[16]; /* Flawfinder: ignore */ + snprintf(source_volume, sizeof(source_volume), "%s", /* Flawfinder: ignore */ mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); - success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume"); + + success &= dp.packBinaryDataFixed((U8*)source_volume, 16, "source_volume"); success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); + char target_volume[16]; /* Flawfinder: ignore */ if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { - snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */ + snprintf(target_volume,sizeof(target_volume), "%s", "GROUND"); /* Flawfinder: ignore */ } else { - snprintf(volume_name, sizeof(volume_name),"%s", /* Flawfinder: ignore */ + snprintf(target_volume, sizeof(target_volume),"%s", /* Flawfinder: ignore */ mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str()); } - success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "target_volume"); + success &= dp.packBinaryDataFixed((U8*)target_volume, 16, "target_volume"); success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset"); success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir"); success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start"); success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop"); success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start"); success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop"); + + LL_DEBUGS("BVH") << " chain_length " << shared_constraintp->mChainLength << LL_ENDL; + LL_DEBUGS("BVH") << " constraint_type " << (S32)shared_constraintp->mConstraintType << LL_ENDL; + LL_DEBUGS("BVH") << " source_volume " << source_volume << LL_ENDL; + LL_DEBUGS("BVH") << " source_offset " << shared_constraintp->mSourceConstraintOffset << LL_ENDL; + LL_DEBUGS("BVH") << " target_volume " << target_volume << LL_ENDL; + LL_DEBUGS("BVH") << " target_offset " << shared_constraintp->mTargetConstraintOffset << LL_ENDL; + LL_DEBUGS("BVH") << " target_dir " << shared_constraintp->mTargetConstraintDir << LL_ENDL; + LL_DEBUGS("BVH") << " ease_in_start " << shared_constraintp->mEaseInStartTime << LL_ENDL; + LL_DEBUGS("BVH") << " ease_in_stop " << shared_constraintp->mEaseInStopTime << LL_ENDL; + LL_DEBUGS("BVH") << " ease_out_start " << shared_constraintp->mEaseOutStartTime << LL_ENDL; + LL_DEBUGS("BVH") << " ease_out_stop " << shared_constraintp->mEaseOutStopTime << LL_ENDL; } return success; @@ -1971,6 +2020,51 @@ U32 LLKeyframeMotion::getFileSize() return dp.getCurrentSize(); } +//----------------------------------------------------------------------------- +// dumpToFile() +//----------------------------------------------------------------------------- +void LLKeyframeMotion::dumpToFile(const std::string& name) +{ + if (isLoaded()) + { + std::string outfile_base; + if (!name.empty()) + { + outfile_base = name; + } + else if (!getName().empty()) + { + outfile_base = getName(); + } + else + { + const LLUUID& id = getID(); + outfile_base = id.asString(); + } + std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + if (LLFile::isfile(outfilename)) + { + return; + } + + S32 file_size = getFileSize(); + U8* buffer = new U8[file_size]; + + LL_DEBUGS("BVH") << "Dumping " << outfilename << LL_ENDL; + LLDataPackerBinaryBuffer dp(buffer, file_size); + if (serialize(dp)) + { + LLAPRFile outfile; + outfile.open(outfilename, LL_APR_WPB); + if (outfile.getFileHandle()) + { + outfile.write(buffer, file_size); + } + } + delete [] buffer; + } +} + //----------------------------------------------------------------------------- // getPelvisBBox() //----------------------------------------------------------------------------- @@ -2164,8 +2258,8 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, U8* buffer = new U8[size]; file.read((U8*)buffer, size); /*Flawfinder: ignore*/ - - LL_DEBUGS() << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; + + LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; LLDataPackerBinaryBuffer dp(buffer, size); if (motionp->deserialize(dp)) diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index b1422b2b903c742a0d4e13d1fd816666f0a3e9e1..f1fa56d731de6dcb821619095919902a50774b55 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -153,6 +153,7 @@ class LLKeyframeMotion : BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp); BOOL isLoaded() { return mJointMotionList != NULL; } + void dumpToFile(const std::string& name); // setters for modifying a keyframe animation diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index fdeddf55e16538326b600342b7fa0b4e55d55b07..02c1d3cdbd75947c35fd4b0d2c13bbb0903cb489 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -201,10 +201,12 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) //------------------------------------------------------------------------- // propagate joint positions to internal versions //------------------------------------------------------------------------- + // SL-315 mPelvisJoint.setPosition( root_world_pos + mPelvisState->getPosition() ); + // SL-315 mHipLeftJoint.setPosition( mHipLeftState->getJoint()->getPosition() ); mKneeLeftJoint.setPosition( mKneeLeftState->getJoint()->getPosition() ); mAnkleLeftJoint.setPosition( mAnkleLeftState->getJoint()->getPosition() ); @@ -213,6 +215,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) mKneeLeftJoint.setScale( mKneeLeftState->getJoint()->getScale() ); mAnkleLeftJoint.setScale( mAnkleLeftState->getJoint()->getScale() ); + // SL-315 mHipRightJoint.setPosition( mHipRightState->getJoint()->getPosition() ); mKneeRightJoint.setPosition( mKneeRightState->getJoint()->getPosition() ); mAnkleRightJoint.setPosition( mAnkleRightState->getJoint()->getPosition() ); @@ -265,6 +268,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) mCharacter->getGround( mAnkleLeftJoint.getWorldPosition(), mPositionLeft, mNormalLeft); mCharacter->getGround( mAnkleRightJoint.getWorldPosition(), mPositionRight, mNormalRight); + // SL-315 mTargetLeft.setPosition( mPositionLeft ); mTargetRight.setPosition( mPositionRight ); } diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index 4803f855de98853a96a0f5364ae98b6f4d47868d..697efc8157fde7bb4cd8132043a7fad589300516 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -55,7 +55,7 @@ LLMotion::LLMotion( const LLUUID &id ) : mDeactivateCallbackUserData(NULL) { for (S32 i=0; i<3; ++i) - memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); + memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); } //----------------------------------------------------------------------------- @@ -111,9 +111,15 @@ void LLMotion::addJointState(const LLPointer<LLJointState>& jointState) U32 usage = jointState->getUsage(); // for now, usage is everything - mJointSignature[0][jointState->getJoint()->getJointNum()] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0; - mJointSignature[1][jointState->getJoint()->getJointNum()] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0; - mJointSignature[2][jointState->getJoint()->getJointNum()] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0; + S32 joint_num = jointState->getJoint()->getJointNum(); + if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) + { + LL_WARNS() << "joint_num " << joint_num << " is outside of legal range [0-" << LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << jointState->getJoint()->getName() << LL_ENDL; + return; + } + mJointSignature[0][joint_num] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0; + mJointSignature[1][joint_num] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0; + mJointSignature[2][joint_num] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0; } void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata ) diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index 5e37f094b8967ec53699ccfae4c797954a039ebf..2dfc3afc7f0964ba71fa7defcb69db4e3272573f 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -181,7 +181,7 @@ class LLMotion F32 mSendStopTimestamp; // time when simulator should be told to stop this motion F32 mResidualWeight; // blend weight at beginning of stop motion phase F32 mFadeWeight; // for fading in and out based on LOD - U8 mJointSignature[3][LL_CHARACTER_MAX_JOINTS]; // signature of which joints are animated at what priority + U8 mJointSignature[3][LL_CHARACTER_MAX_ANIMATED_JOINTS]; // signature of which joints are animated at what priority void (*mDeactivateCallback)(void* data); void* mDeactivateCallbackUserData; }; diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index e02b139608fc6cb2abd04b86dff83b645591cce8..d8185aa693e65ce3a0b993d55dda45ae32407f3f 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -37,7 +37,8 @@ #include "llanimationstates.h" #include "llstl.h" -const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_JOINTS / 4; +// This is why LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be a multiple of 4. +const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_ANIMATED_JOINTS / 4; const U32 MAX_MOTION_INSTANCES = 32; //----------------------------------------------------------------------------- @@ -488,8 +489,8 @@ void LLMotionController::updateAdditiveMotions() //----------------------------------------------------------------------------- void LLMotionController::resetJointSignatures() { - memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); - memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); + memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); } //----------------------------------------------------------------------------- @@ -553,9 +554,9 @@ static LLTrace::BlockTimerStatHandle FTM_MOTION_ON_UPDATE("Motion onUpdate"); void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) { BOOL update_result = TRUE; - U8 last_joint_signature[LL_CHARACTER_MAX_JOINTS]; + U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; - memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); + memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); // iterate through active motions in chronological order for (motion_list_t::iterator iter = mActiveMotions.begin(); @@ -576,7 +577,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } else { - // NUM_JOINT_SIGNATURE_STRIDES should be multiple of 4 for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) { U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index 2bd5271c4f73a0775985fa7f8eab83b8c3f7dfd7..72de3316947f1ce13fcca68848e087bf30e95e2d 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -223,7 +223,7 @@ class LLMotionController S32 mTimeStepCount; F32 mLastInterp; - U8 mJointSignature[2][LL_CHARACTER_MAX_JOINTS]; + U8 mJointSignature[2][LL_CHARACTER_MAX_ANIMATED_JOINTS]; }; //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index b1a7ebb159612bdbde8e68b3178c6c8d2f62d383..fc95fafd61490f81a3b8494afdc4bc5ce24a2ea8 100644 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -386,6 +386,7 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now) } // apply transforms + // SL-315 target_joint->setPosition(blended_pos + added_pos); target_joint->setScale(blended_scale + added_scale); target_joint->setRotation(added_rot * blended_rot); @@ -417,6 +418,7 @@ void LLJointStateBlender::interpolate(F32 u) return; } + // SL-315 target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u)); target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u)); target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation())); @@ -444,6 +446,7 @@ void LLJointStateBlender::resetCachedJoint() return; } LLJoint* source_joint = mJointStates[0]->getJoint(); + // SL-315 mJointCache.setPosition(source_joint->getPosition()); mJointCache.setScale(source_joint->getScale()); mJointCache.setRotation(source_joint->getRotation()); diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index c6b97d7e8b4f18f0a0fddc2eb80ef09c6bf59c56..0ad063fd1e113109e612ddfd5064dced4a1caf53 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -150,6 +150,7 @@ class LLVisualParam F32 getWeight() const { return mIsAnimating ? mTargetWeight : mCurWeight; } F32 getCurrentWeight() const { return mCurWeight; } F32 getLastWeight() const { return mLastWeight; } + void setLastWeight(F32 val) { mLastWeight = val; } BOOL isAnimating() const { return mIsAnimating; } BOOL isTweakable() const { return (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) || (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT); } diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp index da151808f21c660f6e57c922d848af356f4889c8..617f31b0e46e5877198f25ce8263606ac93a9422 100644 --- a/indra/llcharacter/tests/lljoint_test.cpp +++ b/indra/llcharacter/tests/lljoint_test.cpp @@ -88,6 +88,7 @@ namespace tut { LLJoint lljoint; LLVector3 vec3(2.3f,30.f,10.f); + // SL-315 lljoint.setPosition(vec3); LLVector3 pos = lljoint.getPosition(); ensure("setPosition()/getPosition() failed ", (vec3 == pos)); @@ -98,6 +99,7 @@ namespace tut { LLJoint lljoint; LLVector3 vec3(2.3f,30.f,10.f); + // SL-315 lljoint.setWorldPosition(vec3); LLVector3 pos = lljoint.getWorldPosition(); ensure("1:setWorldPosition()/getWorldPosition() failed ", (vec3 == pos)); diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 0468015bfafeeaff443dab82e266efad1592f405..622ff6f1a43b0d511cb0268c4b89e11f460b87da 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -39,6 +39,7 @@ set(llcommon_SOURCE_FILES llbase64.cpp llbitpack.cpp llcallbacklist.cpp + llcallstack.cpp llcommon.cpp llcommonutils.cpp llcoros.cpp @@ -114,6 +115,7 @@ set(llcommon_SOURCE_FILES llworkerthread.cpp timing.cpp u64.cpp + StackWalker.cpp ) set(llcommon_HEADER_FILES @@ -134,6 +136,7 @@ set(llcommon_HEADER_FILES llbitpack.h llboost.h llcallbacklist.h + llcallstack.h llcommon.h llcommonutils.h llcoros.h @@ -236,6 +239,7 @@ set(llcommon_HEADER_FILES stringize.h timer.h u64.h + StackWalker.h ) set_source_files_properties(${llcommon_HEADER_FILES} diff --git a/indra/llcommon/StackWalker.cpp b/indra/llcommon/StackWalker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0d3104099f49cc7c87e856b50112fe9c3066399 --- /dev/null +++ b/indra/llcommon/StackWalker.cpp @@ -0,0 +1,1388 @@ +/********************************************************************** + * + * StackWalker.cpp + * http://stackwalker.codeplex.com/ + * + * + * $LicenseInfo:firstyear=2016&license=bsd$ + * + * Linden notes: Small modifications from the original source at https://stackwalker.codeplex.com/ + * + * History: + * 2005-07-27 v1 - First public release on http://www.codeproject.com/ + * http://www.codeproject.com/threads/StackWalker.asp + * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack + * (to simplify the usage) + * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL + * (should also be enough) + * - Changed to compile correctly with the PSDK of VC7.0 + * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined: + * it uses LPSTR instead of LPCSTR as first paremeter) + * - Added declarations to support VC5/6 without using 'dbghelp.h' + * - Added a 'pUserData' member to the ShowCallstack function and the + * PReadProcessMemoryRoutine declaration (to pass some user-defined data, + * which can be used in the readMemoryFunction-callback) + * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default + * - Added example for doing an exception-callstack-walking in main.cpp + * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268) + * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse! + * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx + * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx + * Fixed Bug: Compiling with "/Wall" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx + * Fixed Bug: Now checking SymUseSymSrv + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx + * Fixed Bug: Support for recursive function calls + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx + * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx + * Fixed Bug: SymDia is number 7, not 9! + * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8! + * Thanks to Teajay which reported the bug... + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx + * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory + * Thanks to Luiz Salamon which reported this "bug"... + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx + * 2009-04-10 v9 License slihtly corrected (<ORGANIZATION> replaced) + * 2009-11-01 v10 Moved to http://stackwalker.codeplex.com/ + * 2009-11-02 v11 Now try to use IMAGEHLP_MODULE64_V3 if available + * 2010-04-15 v12 Added support for VS2010 RTM + * 2010-05-25 v13 Now using secure MyStrcCpy. Thanks to luke.simon: + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx + * 2013-01-07 v14 Runtime Check Error VS2010 Debug Builds fixed: + * http://stackwalker.codeplex.com/workitem/10511 + * + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2013, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ +#if LL_WINDOWS + +#include <windows.h> +#include <tchar.h> +#include <stdio.h> +#include <stdlib.h> +#pragma comment(lib, "version.lib") // for "VerQueryValue" +#pragma warning(disable:4826) + +#include "StackWalker.h" + + +// If VC7 and later, then use the shipped 'dbghelp.h'-file +#pragma pack(push,8) +#if _MSC_VER >= 1300 +#include <dbghelp.h> +#else +// inline the important dbghelp.h-declarations... +typedef enum { + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; +typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; +typedef struct _IMAGEHLP_MODULE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; +typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; +typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; +typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; +typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 Reserved[8]; +} KDHELP64, *PKDHELP64; +typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ); +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( + HANDLE hProcess, + DWORD64 AddrBase + ); +typedef +DWORD64 +(__stdcall *PGET_MODULE_BASE_ROUTINE64)( + HANDLE hProcess, + DWORD64 Address + ); +typedef +DWORD64 +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( + HANDLE hProcess, + HANDLE hThread, + LPADDRESS64 lpaddr + ); +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_DEBUG 0x80000000 +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; +#endif // _MSC_VER < 1300 +#pragma pack(pop) + +// Some missing defines (for VC5/6): +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + + +// secure-CRT_functions are only available starting with VC8 +#if _MSC_VER < 1400 +#define strcpy_s(dst, len, src) strcpy(dst, src) +#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src) +#define strcat_s(dst, len, src) strcat(dst, src) +#define _snprintf_s _snprintf +#define _tcscat_s _tcscat +#endif + +static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc) +{ + if (nMaxDestSize <= 0) return; + strncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE); + szDest[nMaxDestSize-1] = 0; // INFO: _TRUNCATE will ensure that it is nul-terminated; but with older compilers (<1400) it uses "strncpy" and this does not!) +} // MyStrCpy + +// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL') +#define USED_CONTEXT_FLAGS CONTEXT_FULL + + +class StackWalkerInternal +{ +public: + StackWalkerInternal(StackWalker *parent, HANDLE hProcess) + { + m_parent = parent; + m_hDbhHelp = NULL; + pSC = NULL; + m_hProcess = hProcess; + m_szSymPath = NULL; + pSFTA = NULL; + pSGLFA = NULL; + pSGMB = NULL; + pSGMI = NULL; + pSGO = NULL; + pSGSFA = NULL; + pSI = NULL; + pSLM = NULL; + pSSO = NULL; + pSW = NULL; + pUDSN = NULL; + pSGSP = NULL; + } + ~StackWalkerInternal() + { + if (pSC != NULL) + pSC(m_hProcess); // SymCleanup + if (m_hDbhHelp != NULL) + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + m_parent = NULL; + if(m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + } + BOOL Init(LPCSTR szSymPath) + { + if (m_parent == NULL) + return FALSE; + // Dynamically load the Entry-Points for dbghelp.dll: + // First try to load the newsest one from + TCHAR szTemp[4096]; + // But before wqe do this, we first check if the ".local" file exists + if (GetModuleFileName(NULL, szTemp, 4096) > 0) + { + _tcscat_s(szTemp, _T(".local")); + if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES) + { + // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows" + // Ok, first try the new path according to the archtitecture: +#ifdef _M_IX86 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_X64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_IA64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + // If still not found, try the old directories... + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#if defined _M_X64 || defined _M_IA64 + // Still not found? Then try to load the (old) 64-Bit version: + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll")); + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + } + } + if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one + m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") ); + if (m_hDbhHelp == NULL) + return FALSE; + pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" ); + pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" ); + + pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" ); + pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" ); + pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" ); + + pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" ); + pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" ); + pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" ); + pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); + pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" ); + pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" ); + pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" ); + pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" ); + + if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || + pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || + pSW == NULL || pUDSN == NULL || pSLM == NULL ) + { + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + pSC = NULL; + return FALSE; + } + + // SymInitialize + if (szSymPath != NULL) + m_szSymPath = _strdup(szSymPath); + if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE) + this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0); + + DWORD symOptions = this->pSGO(); // SymGetOptions + symOptions |= SYMOPT_LOAD_LINES; + symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; + //symOptions |= SYMOPT_NO_PROMPTS; + // SymSetOptions + symOptions = this->pSSO(symOptions); + + char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0}; + if (this->pSGSP != NULL) + { + if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE) + this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0); + } + char szUserName[1024] = {0}; + DWORD dwSize = 1024; + GetUserNameA(szUserName, &dwSize); + this->m_parent->OnSymInit(buf, symOptions, szUserName); + + return TRUE; + } + + StackWalker *m_parent; + + HMODULE m_hDbhHelp; + HANDLE m_hProcess; + LPSTR m_szSymPath; + +#pragma pack(push,8) +typedef struct IMAGEHLP_MODULE64_V3 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name + // new elements: 07-Jun-2002 + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +}; + +typedef struct IMAGEHLP_MODULE64_V2 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +}; +#pragma pack(pop) + + + // SymCleanup() + typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); + tSC pSC; + + // SymFunctionTableAccess64() + typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase ); + tSFTA pSFTA; + + // SymGetLineFromAddr64() + typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ); + tSGLFA pSGLFA; + + // SymGetModuleBase64() + typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr ); + tSGMB pSGMB; + + // SymGetModuleInfo64() + typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo ); + tSGMI pSGMI; + + // SymGetOptions() + typedef DWORD (__stdcall *tSGO)( VOID ); + tSGO pSGO; + + // SymGetSymFromAddr64() + typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ); + tSGSFA pSGSFA; + + // SymInitialize() + typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); + tSI pSI; + + // SymLoadModule64() + typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, + IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ); + tSLM pSLM; + + // SymSetOptions() + typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); + tSSO pSSO; + + // StackWalk64() + typedef BOOL (__stdcall *tSW)( + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); + tSW pSW; + + // UnDecorateSymbolName() + typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, + DWORD UndecoratedLength, DWORD Flags ); + tUDSN pUDSN; + + typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength); + tSGSP pSGSP; + + +private: + // **************************************** ToolHelp32 ************************ + #define MAX_MODULE_NAME32 255 + #define TH32CS_SNAPMODULE 0x00000008 + #pragma pack( push, 8 ) + typedef struct tagMODULEENTRY32 + { + DWORD dwSize; + DWORD th32ModuleID; // This module + DWORD th32ProcessID; // owning process + DWORD GlblcntUsage; // Global usage count on the module + DWORD ProccntUsage; // Module usage count in th32ProcessID's context + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + HMODULE hModule; // The hModule of this module in th32ProcessID's context + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; + } MODULEENTRY32; + typedef MODULEENTRY32 * PMODULEENTRY32; + typedef MODULEENTRY32 * LPMODULEENTRY32; + #pragma pack( pop ) + + BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid) + { + // CreateToolhelp32Snapshot() + typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); + // Module32First() + typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + // Module32Next() + typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + + // try both dlls... + const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; + HINSTANCE hToolhelp = NULL; + tCT32S pCT32S = NULL; + tM32F pM32F = NULL; + tM32N pM32N = NULL; + + HANDLE hSnap; + MODULEENTRY32 me; + me.dwSize = sizeof(me); + BOOL keepGoing; + size_t i; + + for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ ) + { + hToolhelp = LoadLibrary( dllname[i] ); + if (hToolhelp == NULL) + continue; + pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); + pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First"); + pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next"); + if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) ) + break; // found the functions! + FreeLibrary(hToolhelp); + hToolhelp = NULL; + } + + if (hToolhelp == NULL) + return FALSE; + + hSnap = pCT32S( TH32CS_SNAPMODULE, pid ); + if (hSnap == (HANDLE) -1) + { + FreeLibrary(hToolhelp); + return FALSE; + } + + keepGoing = !!pM32F( hSnap, &me ); + int cnt = 0; + while (keepGoing) + { + this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize); + cnt++; + keepGoing = !!pM32N( hSnap, &me ); + } + CloseHandle(hSnap); + FreeLibrary(hToolhelp); + if (cnt <= 0) + return FALSE; + return TRUE; + } // GetModuleListTH32 + + // **************************************** PSAPI ************************ + typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; + } MODULEINFO, *LPMODULEINFO; + + BOOL GetModuleListPSAPI(HANDLE hProcess) + { + // EnumProcessModules() + typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); + // GetModuleFileNameEx() + typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleBaseName() + typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleInformation() + typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); + + HINSTANCE hPsapi; + tEPM pEPM; + tGMFNE pGMFNE; + tGMBN pGMBN; + tGMI pGMI; + + DWORD i; + //ModuleEntry e; + DWORD cbNeeded; + MODULEINFO mi; + HMODULE *hMods = 0; + char *tt = NULL; + char *tt2 = NULL; + const SIZE_T TTBUFLEN = 8096; + int cnt = 0; + + hPsapi = LoadLibrary( _T("psapi.dll") ); + if (hPsapi == NULL) + return FALSE; + + pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); + pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); + pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); + pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); + if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) ) + { + // we couldn´t find all functions + FreeLibrary(hPsapi); + return FALSE; + } + + hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof(HMODULE))); + tt = (char*) malloc(sizeof(char) * TTBUFLEN); + tt2 = (char*) malloc(sizeof(char) * TTBUFLEN); + if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) ) + goto cleanup; + + if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) + { + //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle ); + goto cleanup; + } + + if ( cbNeeded > TTBUFLEN ) + { + //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); + goto cleanup; + } + + for ( i = 0; i < cbNeeded / sizeof(hMods[0]); i++ ) + { + // base address, size + pGMI(hProcess, hMods[i], &mi, sizeof(mi)); + // image file name + tt[0] = 0; + pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); + // module name + tt2[0] = 0; + pGMBN(hProcess, hMods[i], tt2, TTBUFLEN ); + + DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage); + if (dwRes != ERROR_SUCCESS) + this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0); + cnt++; + } + + cleanup: + if (hPsapi != NULL) FreeLibrary(hPsapi); + if (tt2 != NULL) free(tt2); + if (tt != NULL) free(tt); + if (hMods != NULL) free(hMods); + + return cnt != 0; + } // GetModuleListPSAPI + + DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size) + { + CHAR *szImg = _strdup(img); + CHAR *szMod = _strdup(mod); + DWORD result = ERROR_SUCCESS; + if ( (szImg == NULL) || (szMod == NULL) ) + result = ERROR_NOT_ENOUGH_MEMORY; + else + { + if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0) + result = GetLastError(); + } + ULONGLONG fileVersion = 0; + if ( (m_parent != NULL) && (szImg != NULL) ) + { + // try to retrive the file-version: + if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0) + { + VS_FIXEDFILEINFO *fInfo = NULL; + DWORD dwHandle; + DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle); + if (dwSize > 0) + { + LPVOID vData = malloc(dwSize); + if (vData != NULL) + { + if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) + { + UINT len; + TCHAR szSubBlock[] = _T("\\"); + if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) + fInfo = NULL; + else + { + fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32); + } + } + free(vData); + } + } + } + + // Retrive some additional-infos about the module + IMAGEHLP_MODULE64_V3 Module; + const char *szSymType = "-unknown-"; + if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) + { + switch(Module.SymType) + { + case SymNone: + szSymType = "-nosymbols-"; + break; + case SymCoff: // 1 + szSymType = "COFF"; + break; + case SymCv: // 2 + szSymType = "CV"; + break; + case SymPdb: // 3 + szSymType = "PDB"; + break; + case SymExport: // 4 + szSymType = "-exported-"; + break; + case SymDeferred: // 5 + szSymType = "-deferred-"; + break; + case SymSym: // 6 + szSymType = "SYM"; + break; + case 7: // SymDia: + szSymType = "DIA"; + break; + case 8: //SymVirtual: + szSymType = "Virtual"; + break; + } + } + LPCSTR pdbName = Module.LoadedImageName; + if (Module.LoadedPdbName[0] != 0) + pdbName = Module.LoadedPdbName; + this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, pdbName, fileVersion); + } + if (szImg != NULL) free(szImg); + if (szMod != NULL) free(szMod); + return result; + } +public: + BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId) + { + // first try toolhelp32 + if (GetModuleListTH32(hProcess, dwProcessId)) + return true; + // then try psapi + return GetModuleListPSAPI(hProcess); + } + + + BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V3 *pModuleInfo) + { + memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3)); + if(this->pSGMI == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + // First try to use the larger ModuleInfo-Structure + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); + void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites... + if (pData == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V3)); + static bool s_useV3Version = true; + if (s_useV3Version) + { + if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*) pData) != FALSE) + { + // only copy as much memory as is reserved... + memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V3)); + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); + free(pData); + return TRUE; + } + s_useV3Version = false; // to prevent unneccessarry calls with the larger struct... + } + + // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)... + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2)); + if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*) pData) != FALSE) + { + // only copy as much memory as is reserved... + memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2)); + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + free(pData); + return TRUE; + } + free(pData); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } +}; + +// ############################################################# +StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess) +{ + this->m_verbose = true; + this->m_options = OptionsAll; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} +StackWalker::StackWalker(bool verbose, int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess) +{ + this->m_verbose = verbose; + this->m_options = options; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + if (szSymPath != NULL) + { + this->m_szSymPath = _strdup(szSymPath); + this->m_options |= SymBuildPath; + } + else + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} + +StackWalker::~StackWalker() +{ + if (m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + if (this->m_sw != NULL) + delete this->m_sw; + this->m_sw = NULL; +} + +BOOL StackWalker::LoadModules() +{ + if (this->m_sw == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + if (m_modulesLoaded != FALSE) + return TRUE; + + // Build the sym-path: + char *szSymPath = NULL; + if ( (this->m_options & SymBuildPath) != 0) + { + const size_t nSymPathLen = 4096; + szSymPath = (char*) malloc(nSymPathLen); + if (szSymPath == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + szSymPath[0] = 0; + // Now first add the (optional) provided sympath: + if (this->m_szSymPath != NULL) + { + strcat_s(szSymPath, nSymPathLen, this->m_szSymPath); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + strcat_s(szSymPath, nSymPathLen, ".;"); + + const size_t nTempLen = 1024; + char szTemp[nTempLen]; + // Now add the current directory: + if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + // Now add the path for the main-module: + if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p) + { + // locate the rightmost path separator + if ( (*p == '\\') || (*p == '/') || (*p == ':') ) + { + *p = 0; + break; + } + } // for (search for path separator...) + if (strlen(szTemp) > 0) + { + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + } + if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + // also add the "system32"-directory: + strcat_s(szTemp, nTempLen, "\\system32"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + if ( (this->m_options & SymUseSymSrv) != 0) + { + if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, "SRV*"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, "\\websymbols"); + strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;"); + } + else + strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"); + } + } // if SymBuildPath + + // First Init the whole stuff... + BOOL bRet = this->m_sw->Init(szSymPath); + if (szSymPath != NULL) free(szSymPath); szSymPath = NULL; + if (bRet == FALSE) + { + this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId); + if (bRet != FALSE) + m_modulesLoaded = TRUE; + return bRet; +} + + +// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction +// This has to be done due to a problem with the "hProcess"-parameter in x64... +// Because this class is in no case multi-threading-enabled (because of the limitations +// of dbghelp.dll) it is "safe" to use a static-variable +static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL; +static LPVOID s_readMemoryFunction_UserData = NULL; + +BOOL StackWalker::ShowCallstack(bool verbose, HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData) +{ + m_verbose = verbose; + CONTEXT c; + CallstackEntry csEntry; + IMAGEHLP_SYMBOL64 *pSym = NULL; + StackWalkerInternal::IMAGEHLP_MODULE64_V3 Module; + IMAGEHLP_LINE64 Line; + int frameNum; + bool bLastEntryCalled = true; + int curRecursionCount = 0; + + if (m_modulesLoaded == FALSE) + this->LoadModules(); // ignore the result... + + if (this->m_sw->m_hDbhHelp == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + s_readMemoryFunction = readMemoryFunction; + s_readMemoryFunction_UserData = pUserData; + + if (context == NULL) + { + // If no context is provided, capture the context + // See: https://stackwalker.codeplex.com/discussions/446958 +#if _WIN32_WINNT <= 0x0501 + // If we need to support XP, we need to use the "old way", because "GetThreadId" is not available! + if (hThread == GetCurrentThread()) +#else + if (GetThreadId(hThread) == GetCurrentThreadId()) +#endif + { + GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, USED_CONTEXT_FLAGS); + } + else + { + SuspendThread(hThread); + memset(&c, 0, sizeof(CONTEXT)); + c.ContextFlags = USED_CONTEXT_FLAGS; + if (GetThreadContext(hThread, &c) == FALSE) + { + ResumeThread(hThread); + return FALSE; + } + } + } + else + c = *context; + + // init STACKFRAME for first call + STACKFRAME64 s; // in/out stackframe + memset(&s, 0, sizeof(s)); + DWORD imageType; +#ifdef _M_IX86 + // normally, call ImageNtHeader() and use machine info from PE header + imageType = IMAGE_FILE_MACHINE_I386; + s.AddrPC.Offset = c.Eip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Ebp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Esp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + imageType = IMAGE_FILE_MACHINE_AMD64; + s.AddrPC.Offset = c.Rip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Rsp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Rsp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + imageType = IMAGE_FILE_MACHINE_IA64; + s.AddrPC.Offset = c.StIIP; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.IntSp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrBStore.Offset = c.RsBSP; + s.AddrBStore.Mode = AddrModeFlat; + s.AddrStack.Offset = c.IntSp; + s.AddrStack.Mode = AddrModeFlat; +#else +#error "Platform not supported!" +#endif + + pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + if (!pSym) goto cleanup; // not enough memory... + memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; + + memset(&Line, 0, sizeof(Line)); + Line.SizeOfStruct = sizeof(Line); + + memset(&Module, 0, sizeof(Module)); + Module.SizeOfStruct = sizeof(Module); + + for (frameNum = 0; ; ++frameNum ) + { + // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64()) + // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can + // assume that either you are done, or that the stack is so hosed that the next + // deeper frame could not be found. + // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! + if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) ) + { + // INFO: "StackWalk64" does not set "GetLastError"... + this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset); + break; + } + + csEntry.offset = s.AddrPC.Offset; + csEntry.name[0] = 0; + csEntry.undName[0] = 0; + csEntry.undFullName[0] = 0; + csEntry.offsetFromSmybol = 0; + csEntry.offsetFromLine = 0; + csEntry.lineFileName[0] = 0; + csEntry.lineNumber = 0; + csEntry.loadedImageName[0] = 0; + csEntry.moduleName[0] = 0; + if (s.AddrPC.Offset == s.AddrReturn.Offset) + { + if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) ) + { + this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset); + break; + } + curRecursionCount++; + } + else + curRecursionCount = 0; + if (s.AddrPC.Offset != 0) + { + // we seem to have a valid PC + // show procedure info (SymGetSymFromAddr64()) + if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE) + { + MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name); + // UnDecorateSymbolName() + this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY ); + this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE ); + } + else + { + this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset); + } + + // show line number info, NT5.0-method (SymGetLineFromAddr64()) + if (this->m_sw->pSGLFA != NULL ) + { // yes, we have SymGetLineFromAddr64() + if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE) + { + csEntry.lineNumber = Line.LineNumber; + MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName); + } + else + { + this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset); + } + } // yes, we have SymGetLineFromAddr64() + + if (m_verbose) // getting module info is very slow, skip unless we're being verbose. + { + // show module info (SymGetModuleInfo64()) + if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE) + { // got module info OK + switch ( Module.SymType ) + { + case SymNone: + csEntry.symTypeString = "-nosymbols-"; + break; + case SymCoff: + csEntry.symTypeString = "COFF"; + break; + case SymCv: + csEntry.symTypeString = "CV"; + break; + case SymPdb: + csEntry.symTypeString = "PDB"; + break; + case SymExport: + csEntry.symTypeString = "-exported-"; + break; + case SymDeferred: + csEntry.symTypeString = "-deferred-"; + break; + case SymSym: + csEntry.symTypeString = "SYM"; + break; +#if API_VERSION_NUMBER >= 9 + case SymDia: + csEntry.symTypeString = "DIA"; + break; +#endif + case 8: //SymVirtual: + csEntry.symTypeString = "Virtual"; + break; + default: + //_snprintf( ty, sizeof(ty), "symtype=%ld", (long) Module.SymType ); + csEntry.symTypeString = NULL; + break; + } + + MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName); + csEntry.baseOfImage = Module.BaseOfImage; + MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName); + } // got module info OK + else + { + this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset); + } + } + else + { + MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, "MODULE?"); + } + } // we seem to have a valid PC + + CallstackEntryType et = nextEntry; + if (frameNum == 0) + et = firstEntry; + bLastEntryCalled = false; + this->OnCallstackEntry(et, csEntry); + + if (s.AddrReturn.Offset == 0) + { + bLastEntryCalled = true; + this->OnCallstackEntry(lastEntry, csEntry); + SetLastError(ERROR_SUCCESS); + break; + } + } // for ( frameNum ) + + cleanup: + if (pSym) free( pSym ); + + if (bLastEntryCalled == false) + this->OnCallstackEntry(lastEntry, csEntry); + + if (context == NULL) + ResumeThread(hThread); + + return TRUE; +} + +BOOL __stdcall StackWalker::myReadProcMem( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ) +{ + if (s_readMemoryFunction == NULL) + { + SIZE_T st; + BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD) st; + //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); + return bRet; + } + else + { + return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData); + } +} + +void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if (fileVersion == 0) + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName); + else + { + DWORD v4 = (DWORD) (fileVersion & 0xFFFF); + DWORD v3 = (DWORD) ((fileVersion>>16) & 0xFFFF); + DWORD v2 = (DWORD) ((fileVersion>>32) & 0xFFFF); + DWORD v1 = (DWORD) ((fileVersion>>48) & 0xFFFF); + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4); + } + if (m_verbose) + { + OnOutput(buffer); + } +} + +void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if ( (eType != lastEntry) && (entry.offset != 0) ) + { + if (entry.name[0] == 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)"); + if (entry.undName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName); + if (entry.undFullName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName); + if (entry.lineFileName[0] == 0) + { + MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)"); + if (entry.moduleName[0] == 0) + MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)"); + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name); + } + else + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name); + buffer[STACKWALK_MAX_NAMELEN-1] = 0; + OnOutput(buffer); + } +} + +void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr); + if (m_verbose) + { + OnOutput(buffer); + } +} + +#pragma warning (disable : 4996) + +void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName); + if (m_verbose) + { + OnOutput(buffer); + } + // Also display the OS-version +#if _MSC_VER <= 1200 + OSVERSIONINFOA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA(&ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion); + if (m_verbose) + { + OnOutput(buffer); + } + } +#else + OSVERSIONINFOEXA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion, ver.wSuiteMask, ver.wProductType); + if (m_verbose) + { + OnOutput(buffer); + } + } +#endif +} + +void StackWalker::OnOutput(LPCSTR buffer) +{ + OutputDebugStringA(buffer); +} + +#endif // LL_WINDOWS diff --git a/indra/llcommon/StackWalker.h b/indra/llcommon/StackWalker.h new file mode 100644 index 0000000000000000000000000000000000000000..834f89c471ea13a090dc2773fcf66e86bac4d5d1 --- /dev/null +++ b/indra/llcommon/StackWalker.h @@ -0,0 +1,226 @@ +/********************************************************************** + * + * StackWalker.h + * + * + * + * $LicenseInfo:firstyear=2016&license=bsd$ + * + * Linden notes: Small modifications from the original source at https://stackwalker.codeplex.com/ + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2009, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * **********************************************************************/ + +#if LL_WINDOWS + +// #pragma once is supported starting with _MCS_VER 1000, +// so we need not to check the version (because we only support _MSC_VER >= 1100)! +#pragma once + +#include <windows.h> + +// special defines for VC5/6 (if no actual PSDK is installed): +#if _MSC_VER < 1300 +typedef unsigned __int64 DWORD64, *PDWORD64; +#if defined(_WIN64) +typedef unsigned __int64 SIZE_T, *PSIZE_T; +#else +typedef unsigned long SIZE_T, *PSIZE_T; +#endif +#endif // _MSC_VER < 1300 + +class StackWalkerInternal; // forward +class StackWalker +{ +public: + typedef enum StackWalkOptions + { + // No addition info will be retrived + // (only the address is available) + RetrieveNone = 0, + + // Try to get the symbol-name + RetrieveSymbol = 1, + + // Try to get the line for this symbol + RetrieveLine = 2, + + // Try to retrieve the module-infos + RetrieveModuleInfo = 4, + + // Also retrieve the version for the DLL/EXE + RetrieveFileVersion = 8, + + // Contains all the abouve + RetrieveVerbose = 0xF, + + // Generate a "good" symbol-search-path + SymBuildPath = 0x10, + + // Also use the public Microsoft-Symbol-Server + SymUseSymSrv = 0x20, + + // Contains all the abouve "Sym"-options + SymAll = 0x30, + + // Contains all options (default) + OptionsAll = 0x3F + } StackWalkOptions; + + StackWalker( + bool verbose = true, + int options = OptionsAll, // 'int' is by design, to combine the enum-flags + LPCSTR szSymPath = NULL, + DWORD dwProcessId = GetCurrentProcessId(), + HANDLE hProcess = GetCurrentProcess() + ); + StackWalker(DWORD dwProcessId, HANDLE hProcess); + virtual ~StackWalker(); + + typedef BOOL (__stdcall *PReadProcessMemoryRoutine)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead, + LPVOID pUserData // optional data, which was passed in "ShowCallstack" + ); + + BOOL LoadModules(); + + BOOL ShowCallstack( + bool verbose, + HANDLE hThread = GetCurrentThread(), + const CONTEXT *context = NULL, + PReadProcessMemoryRoutine readMemoryFunction = NULL, + LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback + ); + +#if _MSC_VER >= 1300 +// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public" +// in older compilers in order to use it... starting with VC7 we can declare it as "protected" +protected: +#endif + enum { STACKWALK_MAX_NAMELEN = 4096 }; // max name length for found symbols + +protected: + // Entry for each Callstack-Entry + typedef struct CallstackEntry + { + DWORD64 offset; // if 0, we have no valid entry + CHAR name[STACKWALK_MAX_NAMELEN]; + CHAR undName[STACKWALK_MAX_NAMELEN]; + CHAR undFullName[STACKWALK_MAX_NAMELEN]; + DWORD64 offsetFromSmybol; + DWORD offsetFromLine; + DWORD lineNumber; + CHAR lineFileName[STACKWALK_MAX_NAMELEN]; + DWORD symType; + LPCSTR symTypeString; + CHAR moduleName[STACKWALK_MAX_NAMELEN]; + DWORD64 baseOfImage; + CHAR loadedImageName[STACKWALK_MAX_NAMELEN]; + } CallstackEntry; + + typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry}; + + virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName); + virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion); + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr); + virtual void OnOutput(LPCSTR szText); + + StackWalkerInternal *m_sw; + HANDLE m_hProcess; + DWORD m_dwProcessId; + BOOL m_modulesLoaded; + LPSTR m_szSymPath; + + bool m_verbose; + int m_options; + int m_MaxRecursionCount; + + static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); + + friend StackWalkerInternal; +}; // class StackWalker + + +// The "ugly" assembler-implementation is needed for systems before XP +// If you have a new PSDK and you only compile for XP and later, then you can use +// the "RtlCaptureContext" +// Currently there is no define which determines the PSDK-Version... +// So we just use the compiler-version (and assumes that the PSDK is +// the one which was installed by the VS-IDE) + +// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later... +// But I currently use it in x64/IA64 environments... +//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400) + +#if defined(_M_IX86) +#ifdef CURRENT_THREAD_VIA_EXCEPTION +// TODO: The following is not a "good" implementation, +// because the callstack is only valid in the "__except" block... +#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + EXCEPTION_POINTERS *pExp = NULL; \ + __try { \ + throw 0; \ + } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ + if (pExp != NULL) \ + memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + } while(0); +#else +// The following should be enough for walking the callstack... +#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + __asm call x \ + __asm x: pop eax \ + __asm mov c.Eip, eax \ + __asm mov c.Ebp, ebp \ + __asm mov c.Esp, esp \ + } while(0); +#endif + +#else + +// The following is defined for x86 (XP and higher), x64 and IA64: +#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + RtlCaptureContext(&c); \ +} while(0); +#endif + +#endif // LL_WINDOWS diff --git a/indra/llcommon/llcallstack.cpp b/indra/llcommon/llcallstack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8db291eed189aa7f9c3df8519c368a02139f269f --- /dev/null +++ b/indra/llcommon/llcallstack.cpp @@ -0,0 +1,190 @@ +/** + * @file llcallstack.cpp + * @brief run-time extraction of the current callstack + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, 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$ + */ + +#include "linden_common.h" + +#include "llcommon.h" +#include "llcallstack.h" +#include "StackWalker.h" +#include "llthreadlocalstorage.h" + +#if LL_WINDOWS +class LLCallStackImpl: public StackWalker +{ +public: + LLCallStackImpl(): + StackWalker(false,0) // non-verbose, options = 0 + { + } + ~LLCallStackImpl() + { + } + void getStack(std::vector<std::string>& stack, S32 skip_count=0, bool verbose=false) + { + m_stack.clear(); + ShowCallstack(verbose); + // Skip the first few lines because they're just bookkeeping for LLCallStack, + // plus any additional lines requested to skip. + S32 first_line = skip_count + 3; + for (S32 i=first_line; i<m_stack.size(); ++i) + { + stack.push_back(m_stack[i]); + } + } +protected: + virtual void OnOutput(LPCSTR szText) + { + m_stack.push_back(szText); + } + std::vector<std::string> m_stack; +}; +#else +// Stub - not implemented currently on other platforms. +class LLCallStackImpl +{ +public: + LLCallStackImpl() {} + ~LLCallStackImpl() {} + void getStack(std::vector<std::string>& stack, S32 skip_count=0, bool verbose=false) + { + stack.clear(); + } +}; +#endif + +LLCallStackImpl *LLCallStack::s_impl = NULL; + +LLCallStack::LLCallStack(S32 skip_count, bool verbose): + m_skipCount(skip_count), + m_verbose(verbose) +{ + if (!s_impl) + { + s_impl = new LLCallStackImpl; + } + LLTimer t; + s_impl->getStack(m_strings, m_skipCount, m_verbose); +} + +bool LLCallStack::contains(const std::string& str) +{ + for (std::vector<std::string>::const_iterator it = m_strings.begin(); + it != m_strings.end(); ++it) + { + if (it->find(str) != std::string::npos) + { + return true; + } + } + return false; +} + +std::ostream& operator<<(std::ostream& s, const LLCallStack& call_stack) +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD + std::vector<std::string>::const_iterator it; + for (it=call_stack.m_strings.begin(); it!=call_stack.m_strings.end(); ++it) + { + s << *it; + } +#else + s << "UNAVAILABLE IN RELEASE"; +#endif + return s; +} + +LLContextStrings::LLContextStrings() +{ +} + +// static +LLContextStrings* LLContextStrings::getThreadLocalInstance() +{ + LLContextStrings *cons = LLThreadLocalSingletonPointer<LLContextStrings>::getInstance(); + if (!cons) + { + LLThreadLocalSingletonPointer<LLContextStrings>::setInstance(new LLContextStrings); + } + return LLThreadLocalSingletonPointer<LLContextStrings>::getInstance(); +} + +// static +void LLContextStrings::addContextString(const std::string& str) +{ + LLContextStrings *cons = getThreadLocalInstance(); + //LL_INFOS() << "CTX " << (S32)cons << " ADD " << str << " CNT " << cons->m_contextStrings[str] << LL_ENDL; + cons->m_contextStrings[str]++; +} + +// static +void LLContextStrings::removeContextString(const std::string& str) +{ + LLContextStrings *cons = getThreadLocalInstance(); + cons->m_contextStrings[str]--; + //LL_INFOS() << "CTX " << (S32)cons << " REMOVE " << str << " CNT " << cons->m_contextStrings[str] << LL_ENDL; + if (cons->m_contextStrings[str] == 0) + { + cons->m_contextStrings.erase(str); + } +} + +// static +bool LLContextStrings::contains(const std::string& str) +{ + const std::map<std::string,S32>& strings = + LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->m_contextStrings; + for (std::map<std::string,S32>::const_iterator it = strings.begin(); it!=strings.end(); ++it) + { + if (it->first.find(str) != std::string::npos) + { + return true; + } + } + return false; +} + +// static +void LLContextStrings::output(std::ostream& os) +{ + const std::map<std::string,S32>& strings = + LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->m_contextStrings; + for (std::map<std::string,S32>::const_iterator it = strings.begin(); it!=strings.end(); ++it) + { + os << it->first << "[" << it->second << "]" << "\n"; + } +} + +// static +std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status) +{ + LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->output(s); + return s; +} + +bool LLContextStatus::contains(const std::string& str) +{ + return LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->contains(str); +} diff --git a/indra/llcommon/llcallstack.h b/indra/llcommon/llcallstack.h new file mode 100644 index 0000000000000000000000000000000000000000..1f7a7689d7671e0448cdc8ed6724263215ffe7d2 --- /dev/null +++ b/indra/llcommon/llcallstack.h @@ -0,0 +1,80 @@ +/** + * @file llcallstack.h + * @brief run-time extraction of the current callstack + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, 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$ + */ + +#include <map> + +class LLCallStackImpl; + +class LLCallStack +{ +public: + LLCallStack(S32 skip_count=0, bool verbose=false); + std::vector<std::string> m_strings; + bool m_verbose; + bool contains(const std::string& str); +private: + static LLCallStackImpl *s_impl; + S32 m_skipCount; +}; + +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCallStack& call_stack); + +class LLContextStrings +{ +public: + LLContextStrings(); + static void addContextString(const std::string& str); + static void removeContextString(const std::string& str); + static void output(std::ostream& os); + static LLContextStrings* getThreadLocalInstance(); + static bool contains(const std::string& str); +private: + std::map<std::string,S32> m_contextStrings; +}; + +class LLScopedContextString +{ +public: + LLScopedContextString(const std::string& str): + m_str(str) + { + LLContextStrings::addContextString(m_str); + } + ~LLScopedContextString() + { + LLContextStrings::removeContextString(m_str); + } +private: + std::string m_str; +}; + +// Mostly exists as a class to hook an ostream override to. +struct LLContextStatus +{ + bool contains(const std::string& str); +}; + +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 6a62860c3f1a11da32ed68a878bfae95fac11ee3..7887a942e991d2cf033373b5337bd763e03f6de2 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1488,3 +1488,20 @@ namespace LLError } } +bool debugLoggingEnabled(const std::string& tag) +{ + const char* tags[] = {tag.c_str()}; + ::size_t tag_count = 1; + LLError::CallSite _site(LLError::LEVEL_DEBUG, __FILE__, __LINE__, + typeid(_LL_CLASS_TO_LOG), __FUNCTION__, false, tags, tag_count); + if (LL_UNLIKELY(_site.shouldLog())) + { + return true; + } + else + { + return false; + } +} + + diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 7cbe4334b305f046b8daf0bc510be8ac737955b9..3573b3f44e7851a00732b5b312b765de8e83f684 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -420,4 +420,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; LLError::CallSite& _site(_sites[which]); \ lllog_test_() +// Check at run-time whether logging is enabled, without generating output +bool debugLoggingEnabled(const std::string& tag); + #endif // LL_LLERROR_H diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 0435cb8a08d9515afda8ea2316719b86822c2234..b024b47225a873814b081e773fa8e5c5efb1c829 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -242,7 +242,6 @@ inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key) template <typename K, typename T> inline bool is_in_map(const std::map<K,T>& inmap, const K& key) { - typedef typename std::map<K,T>::const_iterator map_iter; if(inmap.find(key) == inmap.end()) { return false; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 0b10438b9f1380da1b340fbc2c050a90c0592a14..3094b627a2f35b7ecfa8d30661196a6fbd7b4304 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -257,7 +257,13 @@ F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat) if (active_accumulator && active_accumulator->mSize.hasValue()) { - return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), active_accumulator->mSize.getSampleCount() / (accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount()))); + F32 t = 0.0f; + S32 div = accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount(); + if (div > 0) + { + t = active_accumulator->mSize.getSampleCount() / div; + } + return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), t)); } else { @@ -426,7 +432,13 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat ) const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) { - return lerp(accumulator.getMean(), active_accumulator->getMean(), active_accumulator->getSampleCount() / (accumulator.getSampleCount() + active_accumulator->getSampleCount())); + F32 t = 0.0f; + S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount(); + if (div > 0) + { + t = active_accumulator->getSampleCount() / div; + } + return lerp(accumulator.getMean(), active_accumulator->getMean(), t); } else { @@ -506,7 +518,13 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat ) const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) { - return lerp(accumulator.getMean(), active_accumulator->getMean(), active_accumulator->getSampleCount() / (accumulator.getSampleCount() + active_accumulator->getSampleCount())); + F32 t = 0.0f; + S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount(); + if (div > 0) + { + t = active_accumulator->getSampleCount() / div; + } + return lerp(accumulator.getMean(), active_accumulator->getMean(), t); } else { diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index d141298f69b65260bdfba1de551083b9afd3b062..216334752a170c5364c1f675ba7e63ab9b9fb956 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -121,7 +121,7 @@ class LLMatrix4a res.add(z); } - inline void affineTransform(const LLVector4a& v, LLVector4a& res) + inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) { LLVector4a x,y,z; @@ -137,6 +137,43 @@ class LLMatrix4a z.add(mMatrix[3]); res.setAdd(x,z); } + + inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) + { + F32 x = v[0] * mMatrix[0][0] + v[1] * mMatrix[1][0] + v[2] * mMatrix[2][0] + mMatrix[3][0]; + F32 y = v[0] * mMatrix[0][1] + v[1] * mMatrix[1][1] + v[2] * mMatrix[2][1] + mMatrix[3][1]; + F32 z = v[0] * mMatrix[0][2] + v[1] * mMatrix[1][2] + v[2] * mMatrix[2][2] + mMatrix[3][2]; + F32 w = 1.0f; + res.set(x,y,z,w); + } + + inline void affineTransform(const LLVector4a& v, LLVector4a& res) + { + affineTransformSSE(v,res); + } }; +inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) +{ + LLVector4a result; + result = _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(0, 0, 0, 0)), mat.mMatrix[0]); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(1, 1, 1, 1)), mat.mMatrix[1])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(2, 2, 2, 2)), mat.mMatrix[2])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(3, 3, 3, 3)), mat.mMatrix[3])); + return result; +} + +inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + LLVector4a row0 = rowMul(a.mMatrix[0], b); + LLVector4a row1 = rowMul(a.mMatrix[1], b); + LLVector4a row2 = rowMul(a.mMatrix[2], b); + LLVector4a row3 = rowMul(a.mMatrix[3], b); + + res.mMatrix[0] = row0; + res.mMatrix[1] = row1; + res.mMatrix[2] = row2; + res.mMatrix[3] = row3; +} + #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 567ad9a414ca3313010fc97919d7ae7afa11238b..6f0b4b241062ce7aacca98cf55b752ffcb161769 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2547,7 +2547,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U16 influence = weights[idx++]; influence |= ((U16) weights[idx++] << 8); - F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f); + F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f); wght.mV[cur_influence] = w; joints[cur_influence] = joint; cur_influence++; @@ -2564,11 +2564,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW]; if (wsum <= 0.f) { - wght = LLVector4(0.99999f,0.f,0.f,0.f); + wght = LLVector4(0.999f,0.f,0.f,0.f); } for (U32 k=0; k<4; k++) { - joints_with_weights[k] = (F32) joints[k] + wght[k]; + F32 f_combined = (F32) joints[k] + wght[k]; + joints_with_weights[k] = f_combined; + // Any weights we added above should wind up non-zero and applied to a specific bone. + // A failure here would indicate a floating point precision error in the math. + llassert((k >= cur_influence) || (f_combined - S32(f_combined) > 0.0f)); } face.mWeights[cur_vertex].loadua(joints_with_weights.mV); @@ -4571,6 +4575,7 @@ LLVolumeFace::LLVolumeFace() : mTexCoords(NULL), mIndices(NULL), mWeights(NULL), + mWeightsScrubbed(FALSE), mOctree(NULL), mOptimized(FALSE) { @@ -4596,6 +4601,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTexCoords(NULL), mIndices(NULL), mWeights(NULL), + mWeightsScrubbed(FALSE), mOctree(NULL) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4667,6 +4673,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) ll_aligned_free_16(mWeights); mWeights = NULL; } + mWeightsScrubbed = src.mWeightsScrubbed; } if (mNumIndices) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 1da2d0c6b15f9ea47bed4f9c8b64b693625ddb3d..d66004cdadbc7ef370966497a0351fab69d0a28d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -953,6 +953,8 @@ class LLVolumeFace // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; + mutable BOOL mWeightsScrubbed; + LLOctreeNode<LLVolumeTriangle>* mOctree; //whether or not face has been cache optimized diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 8071d716da467a827ba33a303069bf5f3057fe7b..d73bdd769326da29de463dd7ea191760c858331d 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -807,17 +807,19 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac // LLDAELoader //----------------------------------------------------------------------------- LLDAELoader::LLDAELoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, load_callback_t load_cb, joint_lookup_func_t joint_lookup_func, texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes, + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, U32 modelLimit, - bool preprocess) + bool preprocess) : LLModelLoader( filename, lod, @@ -826,10 +828,12 @@ LLDAELoader::LLDAELoader( texture_load_func, state_cb, opaque_userdata, - jointMap, - jointsFromNodes), -mGeneratedModelLimit(modelLimit), -mPreprocessDAE(preprocess) + jointTransformMap, + jointsFromNodes, + jointAliasMap, + maxJointsPerMesh), + mGeneratedModelLimit(modelLimit), + mPreprocessDAE(preprocess) { } @@ -1148,28 +1152,29 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //Some collada setup for accessing the skeleton - daeElement* pElement = 0; - dae->getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); - - //Try to get at the skeletal instance controller - domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + U32 skeleton_count = dae->getDatabase()->getElementCount( NULL, "skeleton" ); + std::vector<domInstance_controller::domSkeleton*> skeletons; + for (S32 i=0; i<skeleton_count; i++) + { + daeElement* pElement = 0; + dae->getDatabase()->getElement( &pElement, i, 0, "skeleton" ); + + //Try to get at the skeletal instance controller + domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + daeElement* pSkeletonRootNode = NULL; + if (pSkeleton) + { + pSkeletonRootNode = pSkeleton->getValue().getElement(); + } + if (pSkeleton && pSkeletonRootNode) + { + skeletons.push_back(pSkeleton); + } + } bool missingSkeletonOrScene = false; //If no skeleton, do a breadth-first search to get at specific joints - bool rootNode = false; - - //Need to test for a skeleton that does not have a root node - //This occurs when your instance controller does not have an associated scene - if ( pSkeleton ) - { - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - rootNode = true; - } - - } - if ( !pSkeleton || !rootNode ) + if ( skeletons.size() == 0 ) { daeElement* pScene = root->getDescendant("visual_scene"); if ( !pScene ) @@ -1184,7 +1189,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do S32 childCount = children.getCount(); //Process any children that are joints - //Not all children are joints, some code be ambient lights, cameras, geometry etc.. + //Not all children are joints, some could be ambient lights, cameras, geometry etc.. for (S32 i = 0; i < childCount; ++i) { domNode* pNode = daeSafeCast<domNode>(children[i]); @@ -1196,83 +1201,90 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } else - //Has Skeleton - { - //Get the root node of the skeleton - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - //Once we have the root node - start acccessing it's joint components - const int jointCnt = mJointMap.size(); - JointMap :: const_iterator jointIt = mJointMap.begin(); - - //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. - for ( int i=0; i<jointCnt; ++i, ++jointIt ) - { - //Build a joint for the resolver to work with - char str[64]={0}; - sprintf(str,"./%s",(*jointIt).first.c_str() ); - //LL_WARNS()<<"Joint "<< str <<LL_ENDL; - - //Setup the resolver - daeSIDResolver resolver( pSkeletonRootNode, str ); - - //Look for the joint - domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); - if ( pJoint ) - { - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolverA( pJoint, "./translate" ); - domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); - daeSIDResolver jointResolverB( pJoint, "./location" ); - domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); - - LLMatrix4 workingTransform; - - //Translation via SID - if ( pTranslateA ) - { - extractTranslation( pTranslateA, workingTransform ); - } - else - if ( pTranslateB ) - { - extractTranslation( pTranslateB, workingTransform ); - } - else - { - //Translation via child from element - daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); - if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) - { - LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; - missingSkeletonOrScene = true; - } - else - if ( pTranslateElement ) - { - extractTranslationViaElement( pTranslateElement, workingTransform ); - } - else - { - extractTranslationViaSID( pJoint, workingTransform ); - } - - } - - //Store the joint transform w/respect to it's name. - mJointList[(*jointIt).second.c_str()] = workingTransform; - } - } - - //If anything failed in regards to extracting the skeleton, joints or translation id, - //mention it - if ( missingSkeletonOrScene ) - { - LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL; - } - }//got skeleton? - } + //Has one or more skeletons + for (std::vector<domInstance_controller::domSkeleton*>::iterator skel_it = skeletons.begin(); + skel_it != skeletons.end(); ++skel_it) + { + domInstance_controller::domSkeleton* pSkeleton = *skel_it; + //Get the root node of the skeleton + daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); + if ( pSkeletonRootNode ) + { + //Once we have the root node - start acccessing it's joint components + const int jointCnt = mJointMap.size(); + JointMap :: const_iterator jointIt = mJointMap.begin(); + + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. + for ( int i=0; i<jointCnt; ++i, ++jointIt ) + { + //Build a joint for the resolver to work with + char str[64]={0}; + sprintf(str,"./%s",(*jointIt).first.c_str() ); + //LL_WARNS()<<"Joint "<< str <<LL_ENDL; + + //Setup the resolver + daeSIDResolver resolver( pSkeletonRootNode, str ); + + //Look for the joint + domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); + if ( pJoint ) + { + // FIXME this has a lot of overlap with processJointNode(), would be nice to refactor. + + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolverA( pJoint, "./translate" ); + domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); + daeSIDResolver jointResolverB( pJoint, "./location" ); + domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); + + LLMatrix4 workingTransform; + + //Translation via SID + if ( pTranslateA ) + { + extractTranslation( pTranslateA, workingTransform ); + } + else + { + if ( pTranslateB ) + { + extractTranslation( pTranslateB, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; + missingSkeletonOrScene = true; + } + else + if ( pTranslateElement ) + { + extractTranslationViaElement( pTranslateElement, workingTransform ); + } + else + { + extractTranslationViaSID( pJoint, workingTransform ); + } + + } + } + + //Store the joint transform w/respect to its name. + mJointList[(*jointIt).second.c_str()] = workingTransform; + } + } + + //If anything failed in regards to extracting the skeleton, joints or translation id, + //mention it + if ( missingSkeletonOrScene ) + { + LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL; + } + }//got skeleton? + } domSkin::domJoints* joints = skin->getJoints(); @@ -1307,7 +1319,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; + model->mSkinInfo.mJointNums.push_back(-1); } } else @@ -1325,7 +1337,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; + model->mSkinInfo.mJointNums.push_back(-1); } } } @@ -1353,8 +1365,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - - model->mSkinInfo.mInvBindMatrix.push_back(mat); + model->mSkinInfo.mInvBindMatrix.push_back(mat); } } } @@ -1370,35 +1381,48 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do if ( !missingSkeletonOrScene ) { - //Set the joint translations on the avatar - if it's a full mapping - //The joints are reset in the dtor - if ( getRigWithSceneParity() ) - { - JointMap :: const_iterator masterJointIt = mJointMap.begin(); - JointMap :: const_iterator masterJointItEnd = mJointMap.end(); - for (;masterJointIt!=masterJointItEnd;++masterJointIt ) - { - std::string lookingForJoint = (*masterJointIt).first.c_str(); - - if ( mJointList.find( lookingForJoint ) != mJointList.end() ) - { - //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL; - LLMatrix4 jointTransform = mJointList[lookingForJoint]; - LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData); - if ( pJoint ) - { - LLUUID fake_mesh_id; - fake_mesh_id.generate(); - pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, ""); - } - else - { - //Most likely an error in the asset. - LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL; - } - } - } - } + // FIXME: mesh_id is used to determine which mesh gets to + // set the joint offset, in the event of a conflict. Since + // we don't know the mesh id yet, we can't guarantee that + // joint offsets will be applied with the same priority as + // in the uploaded model. If the file contains multiple + // meshes with conflicting joint offsets, preview may be + // incorrect. + LLUUID fake_mesh_id; + fake_mesh_id.generate(); + + //Set the joint translations on the avatar + JointMap :: const_iterator masterJointIt = mJointMap.begin(); + JointMap :: const_iterator masterJointItEnd = mJointMap.end(); + for (;masterJointIt!=masterJointItEnd;++masterJointIt ) + { + std::string lookingForJoint = (*masterJointIt).first.c_str(); + + if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + { + //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL; + LLMatrix4 jointTransform = mJointList[lookingForJoint]; + LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData); + if ( pJoint ) + { + const LLVector3& joint_pos = jointTransform.getTranslation(); + if (pJoint->aboveJointPosThreshold(joint_pos)) + { + bool override_changed; // not used + pJoint->addAttachmentPosOverride(joint_pos, fake_mesh_id, "", override_changed); + if (model->mSkinInfo.mLockScaleIfJointPosition) + { + pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), fake_mesh_id, ""); + } + } + } + else + { + //Most likely an error in the asset. + LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL; + } + } + } } //missingSkeletonOrScene //We need to construct the alternate bind matrix (which contains the new joint positions) @@ -1412,16 +1436,15 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do std::string lookingForJoint = (*jointIt).c_str(); //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key //and store it in the alternate bind matrix - if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + if ( mJointMap.find( lookingForJoint ) != mJointMap.end() ) { - LLMatrix4 jointTransform = mJointList[lookingForJoint]; LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); - } + } else { - LL_WARNS()<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<LL_ENDL; + LL_DEBUGS("Mesh")<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<"] "<<LL_ENDL; } } @@ -1868,7 +1891,7 @@ daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string { return pChildOfElement; } - LL_WARNS()<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; + LL_DEBUGS("Mesh")<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; return NULL; } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 27db5326d50ff8e17721dd19475d7b25b19d2c9a..4e990dbe5e51b887f40ec09501bdd8eabd4b9350 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -47,17 +47,19 @@ class LLDAELoader : public LLModelLoader dae_model_map mModelsMap; LLDAELoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, LLModelLoader::load_callback_t load_cb, LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, U32 modelLimit, - bool preprocess); + bool preprocess); virtual ~LLDAELoader() ; virtual bool OpenFile(const std::string& filename); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index e494c55250145c74704fbc35690bb67b465c78e4..db6d00bc2cfc9b749e0ca7617ac6fdea0d166322 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -50,8 +50,12 @@ std::string model_names[] = const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) - : LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0,0,0) - , mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) + : LLVolume(params, detail), + mNormalizedScale(1,1,1), + mNormalizedTranslation(0,0,0), + mPelvisOffset( 0.0f ), + mStatus(NO_ERRORS), + mSubmodelID(0) { mDecompID = -1; mLocalID = -1; @@ -667,6 +671,7 @@ LLSD LLModel::writeModel( const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, + BOOL lock_scale_if_joint_position, BOOL nowrite, BOOL as_slm, int submodel_id) @@ -686,7 +691,7 @@ LLSD LLModel::writeModel( if (skinning) { //write skinning block - mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); + mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints, lock_scale_if_joint_position); } if (!decomp.mBaseHull.empty() || @@ -867,6 +872,7 @@ LLSD LLModel::writeModel( S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) { + // Note joint index cannot exceed 255. if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) { U8 idx = (U8) iter->mJointIdx; @@ -1000,7 +1006,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { - //1. If a vertex has been weighted then we'll find it via pos and return it's weight list + //1. If a vertex has been weighted then we'll find it via pos and return its weight list weight_map::iterator iterPos = mSkinWeights.begin(); weight_map::iterator iterEnd = mSkinWeights.end(); @@ -1223,7 +1229,6 @@ bool LLModel::loadModel(std::istream& is) } return false; - } bool LLModel::isMaterialListSubset( LLModel* ref ) @@ -1338,7 +1343,6 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn return true; } - bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) { S32 offset = header["skin"]["offset"].asInteger(); @@ -1381,8 +1385,17 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is) return true; } +LLMeshSkinInfo::LLMeshSkinInfo(): + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false) +{ +} -LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin) +LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false) { fromLLSD(skin); } @@ -1394,6 +1407,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) for (U32 i = 0; i < skin["joint_names"].size(); ++i) { mJointNames.push_back(skin["joint_names"][i]); + mJointNums.push_back(-1); } } @@ -1446,9 +1460,18 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) { mPelvisOffset = skin["pelvis_offset"].asReal(); } + + if (skin.has("lock_scale_if_joint_position")) + { + mLockScaleIfJointPosition = skin["lock_scale_if_joint_position"].asBoolean(); + } + else + { + mLockScaleIfJointPosition = false; + } } -LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const +LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const { LLSD ret; @@ -1486,6 +1509,11 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const } } + if (lock_scale_if_joint_position) + { + ret["lock_scale_if_joint_position"] = lock_scale_if_joint_position; + } + ret["pelvis_offset"] = mPelvisOffset; } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ae602c09df55b8098f0e3479e1e85e49f33c5b99..097558ef679a83b50c3bfc33f897439ac9a18910 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -42,18 +42,21 @@ class domMesh; class LLMeshSkinInfo { public: + LLMeshSkinInfo(); + LLMeshSkinInfo(LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; + LLUUID mMeshID; std::vector<std::string> mJointNames; + mutable std::vector<S32> mJointNums; std::vector<LLMatrix4> mInvBindMatrix; std::vector<LLMatrix4> mAlternateBindMatrix; - std::map<std::string, U32> mJointMap; - LLMeshSkinInfo() { } - LLMeshSkinInfo(LLSD& data); - void fromLLSD(LLSD& data); - LLSD asLLSD(bool include_joints) const; LLMatrix4 mBindShapeMatrix; float mPelvisOffset; + bool mLockScaleIfJointPosition; + bool mInvalidJointsScrubbed; }; class LLModel : public LLVolume @@ -138,6 +141,7 @@ class LLModel : public LLVolume const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, + BOOL lock_scale_if_joint_position, BOOL nowrite = FALSE, BOOL as_slm = FALSE, int submodel_id = 0); diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index f86eceb98d8e5dc351c87db8568cdcff4e402146..4e468ff45f57c62785d0bed0ae3537c2a442cb66 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -102,16 +102,18 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& // LLModelLoader //----------------------------------------------------------------------------- LLModelLoader::LLModelLoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, load_callback_t load_cb, joint_lookup_func_t joint_lookup_func, texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes ) -: mJointList( jointMap ) + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointMap& legalJointNamesMap, + U32 maxJointsPerMesh) +: mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") , mFilename(filename) @@ -124,124 +126,14 @@ LLModelLoader::LLModelLoader( , mTextureLoadFunc(texture_load_func) , mStateCallback(state_cb) , mOpaqueData(opaque_userdata) -, mRigParityWithScene(false) -, mRigValidJointUpload(false) -, mLegacyRigValid(false) +, mRigValidJointUpload(true) +, mLegacyRigValid(true) , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) -{ - mJointMap["mPelvis"] = "mPelvis"; - mJointMap["mTorso"] = "mTorso"; - mJointMap["mChest"] = "mChest"; - mJointMap["mNeck"] = "mNeck"; - mJointMap["mHead"] = "mHead"; - mJointMap["mSkull"] = "mSkull"; - mJointMap["mEyeRight"] = "mEyeRight"; - mJointMap["mEyeLeft"] = "mEyeLeft"; - mJointMap["mCollarLeft"] = "mCollarLeft"; - mJointMap["mShoulderLeft"] = "mShoulderLeft"; - mJointMap["mElbowLeft"] = "mElbowLeft"; - mJointMap["mWristLeft"] = "mWristLeft"; - mJointMap["mCollarRight"] = "mCollarRight"; - mJointMap["mShoulderRight"] = "mShoulderRight"; - mJointMap["mElbowRight"] = "mElbowRight"; - mJointMap["mWristRight"] = "mWristRight"; - mJointMap["mHipRight"] = "mHipRight"; - mJointMap["mKneeRight"] = "mKneeRight"; - mJointMap["mAnkleRight"] = "mAnkleRight"; - mJointMap["mFootRight"] = "mFootRight"; - mJointMap["mToeRight"] = "mToeRight"; - mJointMap["mHipLeft"] = "mHipLeft"; - mJointMap["mKneeLeft"] = "mKneeLeft"; - mJointMap["mAnkleLeft"] = "mAnkleLeft"; - mJointMap["mFootLeft"] = "mFootLeft"; - mJointMap["mToeLeft"] = "mToeLeft"; - - mJointMap["avatar_mPelvis"] = "mPelvis"; - mJointMap["avatar_mTorso"] = "mTorso"; - mJointMap["avatar_mChest"] = "mChest"; - mJointMap["avatar_mNeck"] = "mNeck"; - mJointMap["avatar_mHead"] = "mHead"; - mJointMap["avatar_mSkull"] = "mSkull"; - mJointMap["avatar_mEyeRight"] = "mEyeRight"; - mJointMap["avatar_mEyeLeft"] = "mEyeLeft"; - mJointMap["avatar_mCollarLeft"] = "mCollarLeft"; - mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft"; - mJointMap["avatar_mElbowLeft"] = "mElbowLeft"; - mJointMap["avatar_mWristLeft"] = "mWristLeft"; - mJointMap["avatar_mCollarRight"] = "mCollarRight"; - mJointMap["avatar_mShoulderRight"] = "mShoulderRight"; - mJointMap["avatar_mElbowRight"] = "mElbowRight"; - mJointMap["avatar_mWristRight"] = "mWristRight"; - mJointMap["avatar_mHipRight"] = "mHipRight"; - mJointMap["avatar_mKneeRight"] = "mKneeRight"; - mJointMap["avatar_mAnkleRight"] = "mAnkleRight"; - mJointMap["avatar_mFootRight"] = "mFootRight"; - mJointMap["avatar_mToeRight"] = "mToeRight"; - mJointMap["avatar_mHipLeft"] = "mHipLeft"; - mJointMap["avatar_mKneeLeft"] = "mKneeLeft"; - mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft"; - mJointMap["avatar_mFootLeft"] = "mFootLeft"; - mJointMap["avatar_mToeLeft"] = "mToeLeft"; - - - mJointMap["hip"] = "mPelvis"; - mJointMap["abdomen"] = "mTorso"; - mJointMap["chest"] = "mChest"; - mJointMap["neck"] = "mNeck"; - mJointMap["head"] = "mHead"; - mJointMap["figureHair"] = "mSkull"; - mJointMap["lCollar"] = "mCollarLeft"; - mJointMap["lShldr"] = "mShoulderLeft"; - mJointMap["lForeArm"] = "mElbowLeft"; - mJointMap["lHand"] = "mWristLeft"; - mJointMap["rCollar"] = "mCollarRight"; - mJointMap["rShldr"] = "mShoulderRight"; - mJointMap["rForeArm"] = "mElbowRight"; - mJointMap["rHand"] = "mWristRight"; - mJointMap["rThigh"] = "mHipRight"; - mJointMap["rShin"] = "mKneeRight"; - mJointMap["rFoot"] = "mFootRight"; - mJointMap["lThigh"] = "mHipLeft"; - mJointMap["lShin"] = "mKneeLeft"; - mJointMap["lFoot"] = "mFootLeft"; - - //move into joint mapper class - //1. joints for joint offset verification - mMasterJointList.push_front("mPelvis"); - mMasterJointList.push_front("mTorso"); - mMasterJointList.push_front("mChest"); - mMasterJointList.push_front("mNeck"); - mMasterJointList.push_front("mHead"); - mMasterJointList.push_front("mCollarLeft"); - mMasterJointList.push_front("mShoulderLeft"); - mMasterJointList.push_front("mElbowLeft"); - mMasterJointList.push_front("mWristLeft"); - mMasterJointList.push_front("mCollarRight"); - mMasterJointList.push_front("mShoulderRight"); - mMasterJointList.push_front("mElbowRight"); - mMasterJointList.push_front("mWristRight"); - mMasterJointList.push_front("mHipRight"); - mMasterJointList.push_front("mKneeRight"); - mMasterJointList.push_front("mFootRight"); - mMasterJointList.push_front("mHipLeft"); - mMasterJointList.push_front("mKneeLeft"); - mMasterJointList.push_front("mFootLeft"); - - //2. legacy joint list - used to verify rigs that will not be using joint offsets - mMasterLegacyJointList.push_front("mPelvis"); - mMasterLegacyJointList.push_front("mTorso"); - mMasterLegacyJointList.push_front("mChest"); - mMasterLegacyJointList.push_front("mNeck"); - mMasterLegacyJointList.push_front("mHead"); - mMasterLegacyJointList.push_front("mHipRight"); - mMasterLegacyJointList.push_front("mKneeRight"); - mMasterLegacyJointList.push_front("mFootRight"); - mMasterLegacyJointList.push_front("mHipLeft"); - mMasterLegacyJointList.push_front("mKneeLeft"); - mMasterLegacyJointList.push_front("mFootLeft"); - +, mMaxJointsPerMesh(maxJointsPerMesh) +, mJointMap(legalJointNamesMap) +{ assert_main_thread(); sActiveLoaderList.push_back(this) ; } @@ -258,6 +150,23 @@ void LLModelLoader::run() doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } +// static +bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::string& slm_filename) +{ + slm_filename = model_filename; + + std::string::size_type i = model_filename.rfind("."); + if (i != std::string::npos) + { + slm_filename.replace(i, model_filename.size()-1, ".slm"); + return true; + } + else + { + return false; + } +} + bool LLModelLoader::doLoadModel() { //first, look for a .slm file of the same name that was modified later @@ -265,20 +174,17 @@ bool LLModelLoader::doLoadModel() if (mTrySLM) { - std::string filename = mFilename; - - std::string::size_type i = filename.rfind("."); - if (i != std::string::npos) - { - filename.replace(i, filename.size()-1, ".slm"); + std::string slm_filename; + if (getSLMFilename(mFilename, slm_filename)) + { llstat slm_status; - if (LLFile::stat(filename, &slm_status) == 0) + if (LLFile::stat(slm_filename, &slm_status) == 0) { //slm file exists llstat dae_status; if (LLFile::stat(mFilename, &dae_status) != 0 || dae_status.st_mtime < slm_status.st_mtime) { - if (loadFromSLM(filename)) + if (loadFromSLM(slm_filename)) { //slm successfully loaded, if this fails, fall through and //try loading from dae @@ -476,8 +382,6 @@ void LLModelLoader::loadModelCallback() //----------------------------------------------------------------------------- void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ) { - critiqueJointToNodeMappingFromScene(); - //Determines the following use cases for a rig: //1. It is suitable for upload with skin weights & joint positions, or //2. It is suitable for upload as standard av with just skin weights @@ -485,59 +389,27 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset ); bool isRigLegacyOK = isRigLegacy( jointListFromAsset ); - //It's OK that both could end up being true, both default to false - if ( isJointPositionUploadOK ) + // It's OK that both could end up being true. + + // Both start out as true and are forced to false if any mesh in + // the model file is not vald by that criterion. Note that a file + // can contain multiple meshes. + if ( !isJointPositionUploadOK ) { - setRigValidForJointPositionUpload( true ); + // This starts out true, becomes false if false for any loaded + // mesh. + setRigValidForJointPositionUpload( false ); } - if ( isRigLegacyOK) + if ( !isRigLegacyOK) { - setLegacyRigValid( true ); + // This starts out true, becomes false if false for any loaded + // mesh. + setLegacyRigValid( false ); } } -//----------------------------------------------------------------------------- -// critiqueJointToNodeMappingFromScene() -//----------------------------------------------------------------------------- -void LLModelLoader::critiqueJointToNodeMappingFromScene( void ) -{ - //Do the actual nodes back the joint listing from the dae? - //if yes then this is a fully rigged asset, otherwise it's just a partial rig - - JointSet::iterator jointsFromNodeIt = mJointsFromNode.begin(); - JointSet::iterator jointsFromNodeEndIt = mJointsFromNode.end(); - bool result = true; - - if ( !mJointsFromNode.empty() ) - { - for ( ;jointsFromNodeIt!=jointsFromNodeEndIt;++jointsFromNodeIt ) - { - std::string name = *jointsFromNodeIt; - if ( mJointTransformMap.find( name ) != mJointTransformMap.end() ) - { - continue; - } - else - { - LL_INFOS() <<"critiqueJointToNodeMappingFromScene is missing a: " << name << LL_ENDL; - result = false; - } - } - } - else - { - result = false; - } - //Determines the following use cases for a rig: - //1. Full av rig w/1-1 mapping from the scene and joint array - //2. Partial rig but w/o parity between the scene and joint array - if ( result ) - { - setRigWithSceneParity( true ); - } -} //----------------------------------------------------------------------------- // isRigLegacy() //----------------------------------------------------------------------------- @@ -549,68 +421,39 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs return false; } - bool result = false; - - JointSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); - JointSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); - - std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); - std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); - - for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) - { - result = false; - modelJointIt = jointListFromAsset.begin(); + // Too many joints in asset + if (jointListFromAsset.size()>mMaxJointsPerMesh) + { + LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; + LL_WARNS() << "Skinning disabled due to too many joints" << LL_ENDL; + return false; + } + + // Unknown joints in asset + S32 unknown_joint_count = 0; + for (std::vector<std::string>::const_iterator it = jointListFromAsset.begin(); + it != jointListFromAsset.end(); ++it) + { + if (mJointMap.find(*it)==mJointMap.end()) + { + LL_WARNS() << "Rigged to unrecognized joint name " << *it << LL_ENDL; + unknown_joint_count++; + } + } + if (unknown_joint_count>0) + { + LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL; + return false; + } - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } - } - return result; + return true; } //----------------------------------------------------------------------------- // isRigSuitableForJointPositionUpload() //----------------------------------------------------------------------------- bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ) { - bool result = false; - - JointSet :: const_iterator masterJointIt = mMasterJointList.begin(); - JointSet :: const_iterator masterJointEndIt = mMasterJointList.end(); - - std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); - std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); - - for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) - { - result = false; - modelJointIt = jointListFromAsset.begin(); - - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } - } - return result; + return true; } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index bb4d06dca3c5f9a43de3b322d77d3f535c88207d..d64e0a077352727687d6575da23bc87269266cb6 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -34,10 +34,10 @@ class LLJoint; -typedef std::map<std::string, LLMatrix4> JointTransformMap; -typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt; -typedef std::map<std::string, std::string> JointMap; -typedef std::deque<std::string> JointSet; +typedef std::map<std::string, LLMatrix4> JointTransformMap; +typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt; +typedef std::map<std::string, std::string> JointMap; +typedef std::deque<std::string> JointNameSet; const S32 SLM_SUPPORTED_VERSION = 3; const S32 NUM_LOD = 4; @@ -116,25 +116,30 @@ class LLModelLoader : public LLThread //map of avatar joints as named in COLLADA assets to internal joint names JointMap mJointMap; JointTransformMap& mJointList; - JointSet& mJointsFromNode; + JointNameSet& mJointsFromNode; + U32 mMaxJointsPerMesh; LLModelLoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, LLModelLoader::load_callback_t load_cb, LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes); + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointMap& legalJointNamesMap, + U32 maxJointsPerMesh); virtual ~LLModelLoader() ; virtual void setNoNormalize() { mNoNormalize = true; } virtual void setNoOptimize() { mNoOptimize = true; } virtual void run(); - + + static bool getSLMFilename(const std::string& model_filename, std::string& slm_filename); + // Will try SLM or derived class OpenFile as appropriate // virtual bool doLoadModel(); @@ -158,7 +163,6 @@ class LLModelLoader : public LLThread //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); - void critiqueJointToNodeMappingFromScene( void ); //Determines if a rig is a legacy from the joint list bool isRigLegacy( const std::vector<std::string> &jointListFromAsset ); @@ -166,9 +170,6 @@ class LLModelLoader : public LLThread //Determines if a rig is suitable for upload bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } @@ -180,7 +181,7 @@ class LLModelLoader : public LLThread //----------------------------------------------------------------------------- bool isNodeAJoint(const char* name) { - return mJointMap.find(name) != mJointMap.end(); + return name != NULL && mJointMap.find(name) != mJointMap.end(); } protected: @@ -189,17 +190,14 @@ class LLModelLoader : public LLThread LLModelLoader::joint_lookup_func_t mJointLookupFunc; LLModelLoader::texture_load_func_t mTextureLoadFunc; LLModelLoader::state_callback_t mStateCallback; - void* mOpaqueData; + void* mOpaqueData; - bool mRigParityWithScene; bool mRigValidJointUpload; bool mLegacyRigValid; bool mNoNormalize; bool mNoOptimize; - JointSet mMasterJointList; - JointSet mMasterLegacyJointList; JointTransformMap mJointTransformMap; static std::list<LLModelLoader*> sActiveLoaderList; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index e24d3bb5ba2388ebbe4e7585d394b445c648b7ec..7757198af525935904294419c8e4752decee956e 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -306,6 +306,7 @@ PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL; PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL; PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL; PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv = NULL; PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL; PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL; PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL; @@ -1333,6 +1334,7 @@ void LLGLManager::initExtensions() glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB"); glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB"); glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB"); + glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv"); glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB"); glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB"); glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB"); diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index a95872e883edc17ea44672dcb5b919cb2ddf458f..722dd9050bc1819fb31c72382226805e04f5593b 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -155,6 +155,7 @@ extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB; extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB; extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; +extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB; extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; @@ -422,6 +423,7 @@ extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB; extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB; extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; +extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB; extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; @@ -668,6 +670,7 @@ extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB; extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB; extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; +extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB; extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 58c1186a3e7c9e11a28549b11208af177a06e64c..5d669fb955b086b9c9a3dbec3e8bccbb0ab67dc0 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1257,6 +1257,23 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c } } +void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix3x4fv(mUniform[index], count, transpose, v); + } + } +} + void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { if (mProgramObject > 0) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 0746e8760abfbd5426f60502f631d812f10d12b4..6f10d122cb1d19ffcdf6664b38ba667218876b43 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -115,6 +115,7 @@ class LLGLSLShader void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j); void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); void uniform1i(const LLStaticHashedString& uniform, GLint i); void uniform1f(const LLStaticHashedString& uniform, GLfloat v); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ac5e12c3923b9484ed1d2402ed2804d25618958f..45ba8d6eb715d51f41771c026e3110f8fc6f6238 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -534,6 +534,7 @@ set(viewer_SOURCE_FILES llsidepaneliteminfo.cpp llsidepaneltaskinfo.cpp llsidetraypanelcontainer.cpp + llskinningutil.cpp llsky.cpp llslurl.cpp llsnapshotlivepreview.cpp @@ -1140,6 +1141,7 @@ set(viewer_HEADER_FILES llsidepaneliteminfo.h llsidepaneltaskinfo.h llsidetraypanelcontainer.h + llskinningutil.h llsky.h llslurl.h llsnapshotlivepreview.h diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index de197cc337f3264749879491cb01a188566e5cc5..6b244dcd6960b101b0ab4d9e5162d39632dec80c 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -4.1.3 +5.0.1 diff --git a/indra/newview/app_settings/anim.ini b/indra/newview/app_settings/anim.ini index 63c84e544db9134850205ed7bf9a29ec90e4694a..c24d2749ef90981257d4bf43c05d5426c022f86c 100644 --- a/indra/newview/app_settings/anim.ini +++ b/indra/newview/app_settings/anim.ini @@ -1,87 +1,2 @@ Translations 1.0 -[hip] - relativepos = firstkey - relativerot = firstkey - outname = mPelvis - frame = 0 1 0, 0 0 1, 1 0 0 - -[abdomen] - outname = mTorso - frame = 0 1 0, 0 0 1, 1 0 0 - -[chest] - outname = mChest - frame = 0 1 0, 0 0 1, 1 0 0 - -[neckDummy] - ignore = true - frame = 0 1 0, 0 0 1, 1 0 0 - -[neck] - outname = mNeck - frame = 0 1 0, 0 0 1, 1 0 0 - -[head] - outname = mHead - frame = 0 1 0, 0 0 1, 1 0 0 - -[figureHair] - ignore = true - frame = 0 1 0, 0 0 1, 1 0 0 - -[lCollar] - outname = mCollarLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lShldr] - outname = mShoulderLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lForeArm] - outname = mElbowLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lHand] - outname = mWristLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[rCollar] - outname = mCollarRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rShldr] - outname = mShoulderRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rForeArm] - outname = mElbowRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rHand] - outname = mWristRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[lThigh] - outname = mHipLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lShin] - outname = mKneeLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lFoot] - outname = mAnkleLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[rThigh] - outname = mHipRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rShin] - outname = mKneeRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rFoot] - outname = mAnkleRight - frame = 0 1 0, 0 0 1, 1 0 0 \ No newline at end of file diff --git a/indra/newview/app_settings/keywords_lsl_default.xml b/indra/newview/app_settings/keywords_lsl_default.xml index ddd287faf4b27c2237cf7ee7c12d6dfe5d5cf565..d641883d5ac4026c5c338b1d328866846ef92b04 100644 --- a/indra/newview/app_settings/keywords_lsl_default.xml +++ b/indra/newview/app_settings/keywords_lsl_default.xml @@ -528,7 +528,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>27</integer> + <integer>26</integer> <key>tooltip</key> <string>Attach to the avatar's lower upper leg.</string> </map> @@ -678,6 +678,141 @@ <key>tooltip</key> <string>Attach to the avatar's right upper leg.</string> </map> + <key>ATTACH_LHAND_RING1</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>41</integer> + <key>tooltip</key> + <string>Attach to the avatar's left ring finger.</string> + </map> + <key>ATTACH_RHAND_RING1</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>42</integer> + <key>tooltip</key> + <string>Attach to the avatar's right ring finger.</string> + </map> + <key>ATTACH_TAIL_BASE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>43</integer> + <key>tooltip</key> + <string>Attach to the avatar's tail base.</string> + </map> + <key>ATTACH_TAIL_TIP</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>44</integer> + <key>tooltip</key> + <string>Attach to the avatar's tail tip.</string> + </map> + <key>ATTACH_LWING</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>45</integer> + <key>tooltip</key> + <string>Attach to the avatar's left wing.</string> + </map> + <key>ATTACH_RWING</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>46</integer> + <key>tooltip</key> + <string>Attach to the avatar's right wing.</string> + </map> + <key>ATTACH_FACE_JAW</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>47</integer> + <key>tooltip</key> + <string>Attach to the avatar's jaw.</string> + </map> + <key>ATTACH_FACE_LEAR</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>48</integer> + <key>tooltip</key> + <string>Attach to the avatar's left ear (extended).</string> + </map> + <key>ATTACH_FACE_REAR</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>49</integer> + <key>tooltip</key> + <string>Attach to the avatar's right ear (extended).</string> + </map> + <key>ATTACH_FACE_LEYE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>50</integer> + <key>tooltip</key> + <string>Attach to the avatar's left eye (extended).</string> + </map> + <key>ATTACH_FACE_REYE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>51</integer> + <key>tooltip</key> + <string>Attach to the avatar's right eye (extended).</string> + </map> + <key>ATTACH_FACE_TONGUE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>52</integer> + <key>tooltip</key> + <string>Attach to the avatar's tongue.</string> + </map> + <key>ATTACH_GROIN</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>53</integer> + <key>tooltip</key> + <string>Attach to the avatar's groin.</string> + </map> + <key>ATTACH_HIND_LFOOT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>54</integer> + <key>tooltip</key> + <string>Attach to the avatar's left hind foot.</string> + </map> + <key>ATTACH_HIND_RFOOT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>55</integer> + <key>tooltip</key> + <string>Attach to the avatar's right hind foot.</string> + </map> <key>AVOID_CHARACTERS</key> <map> <key>type</key> @@ -809,7 +944,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>6</integer> + <integer>5</integer> <key>tooltip</key> <string/> </map> @@ -818,7 +953,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>22</integer> + <integer>21</integer> <key>tooltip</key> <string/> </map> @@ -872,7 +1007,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>2048</integer> + <string>0x800</string> <key>tooltip</key> <string/> </map> @@ -1463,9 +1598,9 @@ <key>type</key> <string>float</string> <key>value</key> - <real>0.01745329</real> + <real>0.017453293</real> <key>tooltip</key> - <string>0.01745329 - Number of radians per degree. + <string>0.017453293 - Number of radians per degree. You can use this to convert degrees to radians by multiplying the degrees by this number.</string> </map> <key>DENSITY</key> @@ -1482,7 +1617,7 @@ <key>type</key> <string>string</string> <key>value</key> - <string>0x0A0x0A0x0A</string> + <string>\\n\\n\\n</string> <key>tooltip</key> <string>Indicates the last line of a notecard was read.</string> </map> @@ -2299,7 +2434,7 @@ <key>NULL_KEY</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>00000000-0000-0000-0000-000000000000</uuid> <key>tooltip</key> @@ -2395,6 +2530,15 @@ <key>tooltip</key> <string>Gets the object's name.</string> </map> + <key>OBJECT_OMEGA</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>29</integer> + <key>tooltip</key> + <string>Gets an object's angular velocity.</string> + </map> <key>OBJECT_OWNER</key> <map> <key>type</key> @@ -2404,6 +2548,15 @@ <key>tooltip</key> <string>Gets an object's owner's key. If id is group owned, a NULL_KEY is returned.</string> </map> + <key>OBJECT_PRIM_COUNT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>30</integer> + <key>tooltip</key> + <string>Gets the prim count of the object. The script and target object must be owned by the same owner</string> + </map> <key>OBJECT_PATHFINDING_TYPE</key> <map> <key>type</key> @@ -2494,6 +2647,15 @@ <key>tooltip</key> <string/> </map> + <key>OBJECT_REZZER_KEY</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>32</integer> + <key>tooltip</key> + <string/> + </map> <key>OBJECT_ROOT</key> <map> <key>type</key> @@ -2566,6 +2728,15 @@ <key>tooltip</key> <string>Returns boolean, detailing if temporary is enabled or disabled on the object.</string> </map> + <key>OBJECT_TOTAL_INVENTORY_COUNT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>31</integer> + <key>tooltip</key> + <string>Gets the total inventory count of the object. The script and target object must be owned by the same owner</string> + </map> <key>OBJECT_TOTAL_SCRIPT_COUNT</key> <map> <key>type</key> @@ -3052,6 +3223,33 @@ <key>tooltip</key> <string/> </map> + <key>PASS_ALWAYS</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <string>1</string> + <key>tooltip</key> + <string>Always pass the event.</string> + </map> + <key>PASS_NEVER</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <string>2</string> + <key>tooltip</key> + <string>Always pass the event.</string> + </map> + <key>PASS_IF_NOT_HANDLED</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <string>0</string> + <key>tooltip</key> + <string>Pass the event if there is no script handling the event in the prim.</string> + </map> <key>PASSIVE</key> <map> <key>type</key> @@ -4387,6 +4585,24 @@ <key>tooltip</key> <string/> </map> + <key>PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>5</integer> + <key>tooltip</key> + <string/> + </map> + <key>PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>9</integer> + <key>tooltip</key> + <string/> + </map> <key>PSYS_PART_BF_SOURCE_ALPHA</key> <map> <key>type</key> @@ -4536,7 +4752,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>19</integer> + <integer>7</integer> <key>tooltip</key> <string>Age in seconds of a particle at which it dies.</string> </map> @@ -5061,7 +5277,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>2</integer> + <integer>0</integer> <key>tooltip</key> <string/> </map> @@ -5295,7 +5511,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>64</integer> + <string>0x40</string> <key>tooltip</key> <string>Controls whether the object can be grabbed.\nA grab is the default action when in third person, and is available as the hand tool in build mode. This is useful for physical objects that you don't want other people to be able to trivially disturb. The default is FALSE</string> </map> @@ -5304,7 +5520,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>1024</integer> + <string>0x400</string> <key>tooltip</key> <string>Prevent click-and-drag movement on all prims in the object.</string> </map> @@ -5500,7 +5716,7 @@ <key>TEXTURE_BLANK</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid> <key>tooltip</key> @@ -5509,7 +5725,7 @@ <key>TEXTURE_DEFAULT</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>89556747-24cb-43ed-920b-47caed15465f</uuid> <key>tooltip</key> @@ -5518,7 +5734,7 @@ <key>TEXTURE_MEDIA</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>8b5fec65-8d8d-9dc5-cda8-8fdf2716e361</uuid> <key>tooltip</key> @@ -5527,7 +5743,7 @@ <key>TEXTURE_PLYWOOD</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>89556747-24cb-43ed-920b-47caed15465f</uuid> <key>tooltip</key> @@ -5536,7 +5752,7 @@ <key>TEXTURE_TRANSPARENT</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>8dcd4a48-2d37-4909-9f78-f7a9eb4ef903</uuid> <key>tooltip</key> @@ -5956,7 +6172,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>35</integer> + <integer>31</integer> <key>tooltip</key> <string>The timescale for exponential decay of the linear motors magnitude.</string> </map> @@ -6204,15 +6420,6 @@ <key>tooltip</key> <string>An attempted write data to the key-value store failed due to the data quota being met.</string> </map> - <key>LSL_XP_ERROR_REQUEST_PERM_TIMEOUT</key> - <map> - <key>type</key> - <string>integer</string> - <key>value</key> - <integer>18</integer> - <key>tooltip</key> - <string>The request for experience permissions was ignored and timed out.</string> - </map> <key>XP_ERROR_RETRY_UPDATE</key> <map> <key>type</key> @@ -6562,30 +6769,43 @@ <key>experience_permissions</key> <map> <key>arguments</key> - <map> - <key>agent_id</key> - <map> + <array> + <map> + <key>agent_id</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string>ID of the agent approving permission for the Experience.</string> - </map> - </map> + </map> + </map> + </array> </map> <key>experience_permissions_denied</key> <map> <key>arguments</key> - <map> - <key>agent_id</key> - <map> + <array> + <map> + <key>agent_id</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string>ID of the agent denying permission for the Experience.</string> - </map> - </map> + </map> + </map> + <map> + <key>Reason</key> + <map> + <key>type</key> + <string>integer</string> + <key>tooltip</key> + <string>One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent.</string> + </map> + </map> + </array> <key>tooltip</key> - <string>One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent.</string> + <string>Describes why the Experience permissions were denied for the agent.</string> </map> <key>http_request</key> <map> @@ -7281,15 +7501,17 @@ <key>return</key> <string>integer</string> <key>arguments</key> - <map> - <key>AgentID</key> - <map> + <array> + <map> + <key>AgentID</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string></string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Returns TRUE if the agent is in the Experience and the Experience can run in the current location. @@ -8035,7 +8257,8 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> + <array> + <map> <key>Key</key> <map> <key>type</key> @@ -8043,6 +8266,8 @@ <key>tooltip</key> <string></string> </map> + </map> + <map> <key>Value</key> <map> <key>type</key> @@ -8050,7 +8275,8 @@ <key>tooltip</key> <string></string> </map> - </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to create a key-value pair. Will fail with XP_ERROR_STORAGE_EXCEPTION if the key already exists. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value passed to the function. @@ -8148,15 +8374,17 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> - <key>Key</key> - <map> + <array> + <map> + <key>Key</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to delete a key-value pair. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. @@ -9549,15 +9777,17 @@ <key>return</key> <string>list</string> <key>arguments</key> - <map> - <key>ExperienceID</key> - <map> + <array> + <map> + <key>ExperienceID</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string>May be NULL_KEY to retrieve the details for the script's Experience</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Returns a list with the following Experience properties: [Experience Name, Owner ID, Group ID, Experience ID, State, State Message]. State is an integer corresponding to one of the constants XP_ERROR_... and State Message is the string returned by llGetExperienceErrorMessage for that integer. @@ -9572,15 +9802,17 @@ <key>return</key> <string>string</string> <key>arguments</key> - <map> - <key>Error</key> - <map> + <array> + <map> + <key>Error</key> + <map> <key>type</key> <string>integer</string> <key>tooltip</key> <string>An Experience error code to translate.</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Returns a string describing the error code passed or the string corresponding with XP_ERROR_UNKNOWN_ERROR if the value is not a valid Experience error code. @@ -9930,7 +10162,7 @@ <key>Parameters</key> <map> <key>type</key> - <string>integer</string> + <string>list</string> <key>tooltip</key> <string>A list of PRIM_* property constants to return values of.</string> </map> @@ -10021,7 +10253,7 @@ <key>Parameters</key> <map> <key>type</key> - <string>integer</string> + <string>list</string> <key>tooltip</key> <string>PRIM_* flags.</string> </map> @@ -10782,7 +11014,7 @@ <key>sleep</key> <real>0.0</real> <key>return</key> - <string>void</string> + <string>float</string> <key>arguments</key> <undef/> <key>tooltip</key> @@ -11390,7 +11622,7 @@ <key>sleep</key> <real>0.0</real> <key>return</key> - <string>void</string> + <string>integer</string> <key>arguments</key> <array> <map> @@ -11937,22 +12169,26 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> - <key>First</key> - <map> + <array> + <map> + <key>First</key> + <map> <key>type</key> - <string>string</string> + <string>integer</string> <key>tooltip</key> <string>Index of the first key to return.</string> - </map> - <key>Count</key> - <map> + </map> + </map> + <map> + <key>Count</key> + <map> <key>type</key> - <string>string</string> + <string>integer</string> <key>tooltip</key> <string>The number of keys to return.</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction the request a number of keys from the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. The error XP_ERROR_KEY_NOT_FOUND is returned if First is greater than or equal to the number of keys in the data store. In the success case the subsequent items will be the keys requested. The number of keys returned may be less than requested if the return value is too large or if there is not enough keys remaining. The order keys are returned is not guaranteed but is stable between subsequent calls as long as no keys are added or removed. Because the keys are returned in a comma-delimited list it is not recommended to use commas in key names if this function is used. @@ -11981,7 +12217,7 @@ <key>Rules</key> <map> <key>type</key> - <string>integer</string> + <string>list</string> <key>tooltip</key> <string>Particle system rules list in the format [ rule1, data1, rule2, data2 . . . ruleN, dataN ]</string> </map> @@ -13141,6 +13377,15 @@ <string/> </map> </map> + <map> + <key>Bounce</key> + <map> + <key>type</key> + <string>integer</string> + <key>tooltip</key> + <string/> + </map> + </map> <map> <key>Texture</key> <map> @@ -13159,6 +13404,15 @@ <string/> </map> </map> + <map> + <key>Bounce_Offset</key> + <map> + <key>type</key> + <string>float</string> + <key>tooltip</key> + <string/> + </map> + </map> </array> <key>tooltip</key> <string>Make a fountain of particles. Deprecated: Use llParticleSystem instead.\nMake a fountain of particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead.</string> @@ -13959,7 +14213,7 @@ <key>sleep</key> <real>0.0</real> <key>return</key> - <string>void</string> + <string>float</string> <key>arguments</key> <array> <map> @@ -14098,7 +14352,8 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> + <array> + <map> <key>Key</key> <map> <key>type</key> @@ -14106,7 +14361,8 @@ <key>tooltip</key> <string></string> </map> - </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to retrieve the value associated with the key given. Will fail with XP_ERROR_KEY_NOT_FOUND if the key does not exist. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. @@ -14148,7 +14404,7 @@ <key>Text</key> <map> <key>type</key> - <string>integer</string> + <string>string</string> <key>tooltip</key> <string>Message to be transmitted.</string> </map> @@ -14541,22 +14797,26 @@ <key>return</key> <string>void</string> <key>arguments</key> - <map> - <key>AvatarID</key> - <map> + <array> + <map> + <key>AgentID</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string/> - </map> - <key>unused</key> - <map> + </map> + </map> + <map> + <key>unused</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string>Not used, should be ""</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Ask the agent for permission to participate in an experience. This request is similar to llRequestPermissions with the following permissions: PERMISSION_TAKE_CONTROLS, PERMISSION_TRIGGER_ANIMATION, PERMISSION_ATTACH, PERMISSION_TRACK_CAMERA, PERMISSION_CONTROL_CAMERA and PERMISSION_TELEPORT. However, unlike llRequestPermissions the decision to allow or block the request is persistent and applies to all scripts using the experience grid wide. Subsequent calls to llRequestExperiencePermissions from scripts in the experience will receive the same response automatically with no user interaction. One of experience_permissions or experience_permissions_denied will be generated in response to this call. Outstanding permission requests will be lost if the script is derezzed, moved to another region or reset. @@ -17363,7 +17623,7 @@ <key>ParameterValue</key> <map> <key>type</key> - <string>float</string> + <string>rotation</string> <key>tooltip</key> <string/> </map> @@ -17418,7 +17678,7 @@ <key>ParameterValue</key> <map> <key>type</key> - <string>float</string> + <string>vector</string> <key>tooltip</key> <string/> </map> @@ -18487,36 +18747,44 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> - <key>Key</key> - <map> + <array> + <map> + <key>Key</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - <key>Value</key> - <map> + </map> + </map> + <map> + <key>Value</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - <key>Checked</key> - <map> + </map> + </map> + <map> + <key>Checked</key> + <map> <key>type</key> <string>integer</string> <key>tooltip</key> <string></string> - </map> - <key>OriginalValue</key> - <map> + </map> + </map> + <map> + <key>OriginalValue</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to update the value associated with the key given. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. If Checked is 1 the existing value in the data store must match the OriginalValue passed or XP_ERROR_RETRY_UPDATE will be returned. If Checked is 0 the key will be created if necessary. @@ -18868,31 +19136,8 @@ <key>tooltip</key> <string>Returns the largest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules.</string> </map> - <key>llScaleByFactor</key> - <map> - <key>energy</key> - <real>10.0</real> - <key>sleep</key> - <real>0.0</real> - <key>return</key> - <string>float</string> - <key>arguments</key> - <array> - <map> - <key>Factor</key> - <map> - <key>type</key> - <string>float</string> - <key>tooltip</key> - <string/> - </map> - </map> - </array> - <key>tooltip</key> - <string>Tries to uniformly scale the object by a multiplicative factor. Returns TRUE on success or FALSE on failure.</string> - </map> </map> <key>llsd-lsl-syntax-version</key> - <integer>2</integer> + <integer>2</integer><!-- increment only when the file format changes, not just the content --> </map> </llsd> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e12b8cfecd9617458470f235385f0db2105fb5e9..fa39dd6c651fe5b01ced2dffabd2d6eb82a5c89d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2204,6 +2204,17 @@ <string>String</string> <key>Value</key> <string /> + </map> + <key>DebugAvatarJoints</key> + <map> + <key>Comment</key> + <string>List of joints to emit additional debugging info about.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> </map> <key>DebugAvatarRezTime</key> <map> @@ -3525,6 +3536,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>IncludeEnhancedSkeleton</key> + <map> + <key>Comment</key> + <string>Include extended skeleton joints when rendering skinned meshes.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>MinObjectsForUnlinkConfirm</key> <map> <key>Comment</key> @@ -6396,7 +6418,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>MeshUploadLogXML</key> <map> @@ -14541,6 +14563,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>LogWearableAssetSave</key> + <map> + <key>Comment</key> + <string>Save copy of saved wearables to log dir</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>LogTextureDownloadsToViewerLog</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 3060307b2113920734afcb18b7afca250ec86cde..90bf2851c9e0f49534f19e18a07c6ecdefb66c91 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -24,8 +24,7 @@ ATTRIBUTE vec4 weight4; -uniform mat3 matrixPalette[52]; -uniform vec3 translationPalette[52]; +uniform mat3x4 matrixPalette[MAX_JOINTS_PER_MESH_OBJECT]; mat4 getObjectSkinnedTransform() { @@ -34,8 +33,8 @@ mat4 getObjectSkinnedTransform() vec4 w = fract(weight4); vec4 index = floor(weight4); - index = min(index, vec4(51.0)); - index = max(index, vec4( 0.0)); + index = min(index, vec4(MAX_JOINTS_PER_MESH_OBJECT-1)); + index = max(index, vec4( 0.0)); w *= 1.0/(w.x+w.y+w.z+w.w); @@ -43,16 +42,16 @@ mat4 getObjectSkinnedTransform() int i2 = int(index.y); int i3 = int(index.z); int i4 = int(index.w); - - mat3 mat = matrixPalette[i1]*w.x; - mat += matrixPalette[i2]*w.y; - mat += matrixPalette[i3]*w.z; - mat += matrixPalette[i4]*w.w; - vec3 trans = translationPalette[i1]*w.x; - trans += translationPalette[i2]*w.y; - trans += translationPalette[i3]*w.z; - trans += translationPalette[i4]*w.w; + mat3 mat = mat3(matrixPalette[i1])*w.x; + mat += mat3(matrixPalette[i2])*w.y; + mat += mat3(matrixPalette[i3])*w.z; + mat += mat3(matrixPalette[i4])*w.w; + + vec3 trans = vec3(matrixPalette[i1][0].w,matrixPalette[i1][1].w,matrixPalette[i1][2].w)*w.x; + trans += vec3(matrixPalette[i2][0].w,matrixPalette[i2][1].w,matrixPalette[i2][2].w)*w.y; + trans += vec3(matrixPalette[i3][0].w,matrixPalette[i3][1].w,matrixPalette[i3][2].w)*w.z; + trans += vec3(matrixPalette[i4][0].w,matrixPalette[i4][1].w,matrixPalette[i4][2].w)*w.w; mat4 ret; @@ -65,10 +64,8 @@ mat4 getObjectSkinnedTransform() #ifdef IS_AMD_CARD // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. - mat3 dummy1 = matrixPalette[0]; - vec3 dummy2 = translationPalette[0]; - mat3 dummy3 = matrixPalette[51]; - vec3 dummy4 = translationPalette[51]; + mat3x4 dummy1 = matrixPalette[0]; + mat3x4 dummy2 = matrixPalette[MAX_JOINTS_PER_MESH_OBJECT-1]; #endif } diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 7f7eaed38a13d9e945d4d740be6df4a6ad4efb78..90f06746c9fd733a6bd369c08a922409852b804d 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <linden_avatar - version="1.0" wearable_definition_version="22"> + version="2.0" wearable_definition_version="22"> <!-- The wearable_definition_version is checked during asset upload. --> <!-- If you increment it, check indra/lib/python/indra/assetutil.py. --> <skeleton @@ -11,6 +11,7 @@ pie_slice="2" name="Chest" joint="mChest" + location="ATTACH_CHEST" position="0.15 0 -0.1" rotation="0 90 90" visible_in_first_person="true" /> @@ -21,6 +22,7 @@ pie_slice="2" name="Skull" joint="mHead" + location="ATTACH_HEAD" position="0 0 0.15" rotation="0 0 90" visible_in_first_person="false" /> @@ -31,6 +33,7 @@ pie_slice="3" name="Left Shoulder" joint="mCollarLeft" + location="ATTACH_LSHOULDER" position="0 0 0.08" rotation="0 0 0" visible_in_first_person="true" /> @@ -41,6 +44,7 @@ pie_slice="1" name="Right Shoulder" joint="mCollarRight" + location="ATTACH_RSHOULDER" position="0 0 0.08" rotation="0 0 0" visible_in_first_person="true"/> @@ -50,6 +54,7 @@ group="4" name="Left Hand" joint="mWristLeft" + location="ATTACH_LHAND" position="0 0.08 -0.02" rotation="0 0 0" visible_in_first_person="true" @@ -60,6 +65,7 @@ group="0" name="Right Hand" joint="mWristRight" + location="ATTACH_RHAND" position="0 -0.08 -0.02" rotation="0 0 0" visible_in_first_person="true" @@ -71,6 +77,7 @@ pie_slice="6" name="Left Foot" joint="mFootLeft" + location="ATTACH_LFOOT" position="0 0.0 0.0" rotation="0 0 0" visible_in_first_person="true"/> @@ -81,6 +88,7 @@ pie_slice="6" name="Right Foot" joint="mFootRight" + location="ATTACH_RFOOT" position="0 0.0 0.0" rotation="0 0 0" visible_in_first_person="true"/> @@ -91,6 +99,7 @@ pie_slice="7" name="Spine" joint="mChest" + location="ATTACH_BACK" position="-0.15 0 -0.1" rotation="0 -90 90" visible_in_first_person="true" /> @@ -101,6 +110,7 @@ pie_slice="6" name="Pelvis" joint="mPelvis" + location="ATTACH_PELVIS" position="0 0 -0.15" rotation="0 0 0" visible_in_first_person="true" /> @@ -111,6 +121,7 @@ pie_slice="6" name="Mouth" joint="mHead" + location="ATTACH_MOUTH" position="0.12 0 0.001" rotation="0 0 0" visible_in_first_person="false"/> @@ -121,6 +132,7 @@ pie_slice="7" name="Chin" joint="mHead" + location="ATTACH_CHIN" position="0.12 0 -0.04" rotation="0 0 0" visible_in_first_person="false" /> @@ -131,6 +143,7 @@ pie_slice="4" name="Left Ear" joint="mHead" + location="ATTACH_LEAR" position="0.015 0.08 0.017" rotation="0 0 0" visible_in_first_person="false" /> @@ -141,6 +154,7 @@ pie_slice="0" name="Right Ear" joint="mHead" + location="ATTACH_REAR" position="0.015 -0.08 0.017" rotation="0 0 0" visible_in_first_person="false" /> @@ -151,6 +165,7 @@ pie_slice="3" name="Left Eyeball" joint="mEyeLeft" + location="ATTACH_LEYE" position="0 0 0" rotation="0 0 0" visible_in_first_person="false"/> @@ -161,6 +176,7 @@ pie_slice="1" name="Right Eyeball" joint="mEyeRight" + location="ATTACH_REYE" position="0 0 0" rotation="0 0 0" visible_in_first_person="false" /> @@ -171,6 +187,7 @@ pie_slice="5" name="Nose" joint="mHead" + location="ATTACH_NOSE" position="0.1 0 0.05" rotation="0 0 0" visible_in_first_person="false"/> @@ -181,6 +198,7 @@ pie_slice="0" name="R Upper Arm" joint="mShoulderRight" + location="ATTACH_RUARM" position="0.01 -0.13 0.01" rotation="0 0 0" visible_in_first_person="true" /> @@ -191,6 +209,7 @@ pie_slice="7" name="R Forearm" joint="mElbowRight" + location="ATTACH_RLARM" position="0 -0.12 0" rotation="0 0 0" visible_in_first_person="true"/> @@ -201,6 +220,7 @@ pie_slice="4" name="L Upper Arm" joint="mShoulderLeft" + location="ATTACH_LUARM" position="0.01 0.15 -0.01" rotation="0 0 0" visible_in_first_person="true" /> @@ -211,6 +231,7 @@ pie_slice="5" name="L Forearm" joint="mElbowLeft" + location="ATTACH_LLARM" position="0 0.113 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -221,6 +242,7 @@ pie_slice="1" name="Right Hip" joint="mHipRight" + location="ATTACH_RHIP" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -231,6 +253,7 @@ pie_slice="0" name="R Upper Leg" joint="mHipRight" + location="ATTACH_RULEG" position="-0.017 0.041 -0.310" rotation="0 0 0" visible_in_first_person="true" /> @@ -241,6 +264,7 @@ pie_slice="7" name="R Lower Leg" joint="mKneeRight" + location="ATTACH_RLLEG" position="-0.044 -0.007 -0.262" rotation="0 0 0" visible_in_first_person="true" /> @@ -251,6 +275,7 @@ pie_slice="3" name="Left Hip" joint="mHipLeft" + location="ATTACH_LHIP" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -261,6 +286,7 @@ pie_slice="4" name="L Upper Leg" joint="mHipLeft" + location="ATTACH_LULEG" position="-0.019 -0.034 -0.310" rotation="0 0 0" visible_in_first_person="true"/> @@ -271,6 +297,7 @@ pie_slice="5" name="L Lower Leg" joint="mKneeLeft" + location="ATTACH_LLLEG" position="-0.044 -0.007 -0.261" rotation="0 0 0" visible_in_first_person="true" /> @@ -281,6 +308,7 @@ pie_slice="5" name="Stomach" joint="mPelvis" + location="ATTACH_BELLY" position="0.092 0.0 0.088" rotation="0 0 0" visible_in_first_person="true" /> @@ -291,6 +319,7 @@ pie_slice="3" name="Left Pec" joint="mTorso" + location="ATTACH_LEFT_PEC" position="0.104 0.082 0.247" rotation="0 0 0" visible_in_first_person="true" /> @@ -301,15 +330,17 @@ pie_slice="1" name="Right Pec" joint="mTorso" + location="ATTACH_RIGHT_PEC" position="0.104 -0.082 0.247" rotation="0 0 0" visible_in_first_person="true" /> <attachment_point id="31" - group="8" + group="9" name="Center 2" joint="mScreen" + location="ATTACH_HUD_CENTER_2" position="0 0 0" rotation="0 0 0" hud="true" @@ -318,9 +349,10 @@ <attachment_point id="32" - group="8" + group="9" name="Top Right" joint="mScreen" + location="ATTACH_HUD_TOP_RIGHT" position="0 -0.5 0.5" rotation="0 0 0" hud="true" @@ -329,9 +361,10 @@ <attachment_point id="33" - group="8" + group="9" name="Top" joint="mScreen" + location="ATTACH_HUD_TOP_CENTER" position="0 0 0.5" rotation="0 0 0" hud="true" @@ -340,9 +373,10 @@ <attachment_point id="34" - group="8" + group="9" name="Top Left" joint="mScreen" + location="ATTACH_HUD_TOP_LEFT" position="0 0.5 0.5" rotation="0 0 0" hud="true" @@ -351,9 +385,10 @@ <attachment_point id="35" - group="8" + group="9" name="Center" joint="mScreen" + location="ATTACH_HUD_CENTER_1" position="0 0 0" rotation="0 0 0" hud="true" @@ -362,9 +397,10 @@ <attachment_point id="36" - group="8" + group="9" name="Bottom Left" joint="mScreen" + location="ATTACH_HUD_BOTTOM_LEFT" position="0 0.5 -0.5" rotation="0 0 0" hud="true" @@ -373,9 +409,10 @@ <attachment_point id="37" - group="8" + group="9" name="Bottom" joint="mScreen" + location="ATTACH_HUD_BOTTOM" position="0 0 -0.5" rotation="0 0 0" hud="true" @@ -384,9 +421,10 @@ <attachment_point id="38" - group="8" + group="9" name="Bottom Right" joint="mScreen" + location="ATTACH_HUD_BOTTOM_RIGHT" position="0 -0.5 -0.5" rotation="0 0 0" hud="true" @@ -399,6 +437,7 @@ pie_slice="1" name="Neck" joint="mNeck" + location="ATTACH_NECK" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -409,10 +448,180 @@ pie_slice="2" name="Avatar Center" joint="mRoot" + location="ATTACH_AVATAR_CENTER" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> - + + <!-- BENTO ADDITIONS --> + + <attachment_point + id="41" + group="8" + pie_slice="0" + name="Left Ring Finger" + joint="mHandRing1Left" + location="ATTACH_LHAND_RING1" + position="-0.006 0.019 -0.002" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="42" + group="8" + pie_slice="1" + name="Right Ring Finger" + joint="mHandRing1Right" + location="ATTACH_RHAND_RING1" + position="-0.006 -0.019 -0.002" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="43" + group="8" + pie_slice="2" + name="Tail Base" + joint="mTail1" + location="ATTACH_TAIL_BASE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="44" + group="8" + pie_slice="3" + name="Tail Tip" + joint="mTail6" + location="ATTACH_TAIL_TIP" + position="-0.025 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="45" + group="8" + pie_slice="4" + name="Left Wing" + joint="mWing4Left" + location="ATTACH_LWING" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="46" + group="8" + pie_slice="5" + name="Right Wing" + joint="mWing4Right" + location="ATTACH_RWING" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="47" + group="8" + pie_slice="6" + name="Jaw" + joint="mFaceJaw" + location="ATTACH_FACE_JAW" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="48" + group="8" + pie_slice="7" + name="Alt Left Ear" + joint="mFaceEar1Left" + location="ATTACH_FACE_LEAR" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="49" + group="8" + pie_slice="8" + name="Alt Right Ear" + joint="mFaceEar1Right" + location="ATTACH_FACE_REAR" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="50" + group="8" + pie_slice="9" + name="Alt Left Eye" + joint="mFaceEyeAltLeft" + location="ATTACH_FACE_LEYE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="51" + group="8" + pie_slice="10" + name="Alt Right Eye" + joint="mFaceEyeAltRight" + location="ATTACH_FACE_REYE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="52" + group="8" + pie_slice="11" + name="Tongue" + joint="mFaceTongueTip" + location="ATTACH_FACE_TONGUE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="53" + group="8" + pie_slice="12" + name="Groin" + joint="mGroin" + location="ATTACH_GROIN" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="54" + group="8" + pie_slice="13" + name="Left Hind Foot" + joint="mHindLimb4Left" + location="ATTACH_HIND_LFOOT" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="55" + group="8" + pie_slice="14" + name="Right Hind Foot" + joint="mHindLimb4Right" + location="ATTACH_HIND_RFOOT" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <!-- END BENTO --> + <param id="32" group="1" @@ -460,8 +669,12 @@ scale="0 0 .05" /> <bone - name="mPelvis" - scale="0 0 0" /> + name="mSpine3" + scale="0 0 .05" /> + + <bone + name="mSpine4" + scale="0 0 .05" /> <bone name="mHipLeft" @@ -478,6 +691,29 @@ <bone name="mKneeRight" scale=".05 .05 .1" /> + + <bone + name="mHindLimb1Left" + scale=".05 .05 0" /> + + <bone + name="mHindLimb1Right" + scale=".05 .05 0" /> + + <bone + name="mHindLimb2Left" + scale=".05 .05 .1" /> + + <bone + name="mHindLimb2Right" + scale=".05 .05 .1" /> + + <bone name="mWingsRoot" scale="0 0 0" offset="0 0 0" /> + + <bone name="mWing1Right" scale="0 0 0" offset="-0.05 0 0" /> + + <bone name="mWing1Left" scale="0 0 0" offset="-0.05 0 0" /> + </param_skeleton> </param> @@ -533,8 +769,12 @@ scale="0 0 0.05" /> <bone - name="mPelvis" - scale="0 0 0" /> + name="mSpine3" + scale="0 0 0.05" /> + + <bone + name="mSpine4" + scale="0 0 0.05" /> <bone name="mHipLeft" @@ -551,6 +791,96 @@ <bone name="mKneeRight" scale="0 0 0.1" /> + + <bone + name="mHindLimb1Left" + scale="0 0 0.1" /> + + <bone + name="mHindLimb1Right" + scale="0 0 0.1" /> + + <bone + name="mHindLimb2Left" + scale="0 0 0.1" /> + + <bone + name="mHindLimb2Right" + scale="0 0 0.1" /> + + <bone + name="mWing1Left" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mWing2Left" + scale="0 0 0" + offset="-0.015 0.015 0" /> + <bone + name="mWing3Left" + scale="0 0 0" + offset="-0.025 0.025 0" /> + <bone + name="mWing4Left" + scale="0 0 0" + offset="-0.03 0.03 0" /> + <bone + name="mWing4FanLeft" + scale="0 0 0" + offset="-0.03 0.03 0" /> + + <bone + name="mWing1Right" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mWing2Right" + scale="0 0 0" + offset="-0.015 -0.015 0" /> + <bone + name="mWing3Right" + scale="0 0 0" + offset="-0.025 -0.025 0" /> + <bone + name="mWing4Right" + scale="0 0 0" + offset="-0.03 -0.03 0" /> + <bone + name="mWing4FanRight" + scale="0 0 0" + offset="-0.03 -0.03 0" /> + + <bone + name="mTail1" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail2" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail3" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail4" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail5" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail6" + scale ="0 0 0" + offset="-0.02 0 0" /> + + </param_skeleton> </param> @@ -605,10 +935,26 @@ name="mTorso" scale="0.1 0.1 0" /> + <bone + name="mSpine3" + scale="0.1 0.1 0" /> + + <bone + name="mSpine4" + scale="0.1 0.1 0" /> + <bone name="mPelvis" scale="0.1 0.1 0" /> + <bone + name="mSpine1" + scale="0.1 0.1 0" /> + + <bone + name="mSpine2" + scale="0.1 0.1 0" /> + <bone name="mHipLeft" scale="0.13 0.13 0" /> @@ -624,6 +970,37 @@ <bone name="mKneeRight" scale="0.12 0.12 0" /> + + <bone + name="mHindLimbsRoot" + scale="0.1 0.1 0" /> + + <bone + name="mHindLimb1Left" + scale="0.13 0.13 0" /> + + <bone + name="mHindLimb1Right" + scale="0.13 0.13 0" /> + + <bone + name="mHindLimb2Left" + scale="0.12 0.12 0" /> + + <bone + name="mHindLimb2Right" + scale="0.12 0.12 0" /> + + <bone name="mTail1" scale="0.05 0.1 0.1" /> + <bone name="mTail2" scale="0.05 0.1 0.1" /> + <bone name="mTail3" scale="0.05 0.1 0.1" /> + <bone name="mTail4" scale="0.05 0.1 0.1" /> + <bone name="mTail5" scale="0.05 0.1 0.1" /> + <bone name="mTail6" scale="0.05 0.1 0.1" /> + + <bone name="mWing1Right" scale="0.0 0.0 0.0" offset="-0.01 -0.01 0" /> + <bone name="mWing1Left" scale="0.0 0.0 0.0" offset="-0.01 0.01 0" /> + </param_skeleton> </param> @@ -662,6 +1039,17 @@ <bone name="mChest" scale="0.02 0.08 0" /> + + <bone + name="mWing1Right" + scale="0.0 0.0 0.0" + offset="0 -0.02 0" /> + + <bone + name="mWing1Left" + scale="0.0 0.0 0.0" + offset="0 0.02 0" /> + </param_skeleton> </param> @@ -669,7 +1057,7 @@ id="37" group="0" name="Hip Width" - label="Hip Width" + label="Hip Width" wearable="shape" edit_group="shape_legs" edit_group_order="3" @@ -684,6 +1072,14 @@ name="mPelvis" scale="0 0.1 0" /> + <bone + name="mSpine1" + scale="0 0.1 0" /> + + <bone + name="mSpine2" + scale="0 0.1 0" /> + <bone name="mHipLeft" scale="0 0 0" @@ -693,6 +1089,25 @@ name="mHipRight" scale="0 0 0" offset="0 -.004 0" /> + + <bone + name="mHindLimbsRoot" + scale="0 0.1 0" /> + + <bone + name="mHindLimb1Left" + scale="0 0 0" + offset="0 .004 0" /> + + <bone + name="mHindLimb1Right" + scale="0 0 0" + offset="0 -.004 0" /> + + <bone name="mTail1" scale="0.0 0.05 0" /> + <bone name="mTail2" scale="0.0 0.02 0" /> + <bone name="mTail3" scale="0.0 0.01 0" /> + </param_skeleton> </param> @@ -712,7 +1127,19 @@ <bone name="mPelvis" scale="0 0 0.3" /> - </param_skeleton> + + <bone + name="mHindLimbsRoot" + scale="0 0 0.3" /> + + <bone + name="mSpine1" + scale="0 0 0.3" /> + + <bone + name="mSpine2" + scale="0 0 0.3" /> + </param_skeleton> </param> <param @@ -732,10 +1159,26 @@ name="mTorso" scale="0 0 .3" /> + <bone + name="mSpine3" + scale="0 0 .3" /> + + <bone + name="mSpine4" + scale="0 0 .3" /> + <bone name="mPelvis" scale="0 0 .1" /> + <bone + name="mSpine1" + scale="0 0 .1" /> + + <bone + name="mSpine2" + scale="0 0 .1" /> + <bone name="mHipLeft" scale="0 0 -.1" /> @@ -751,6 +1194,26 @@ <bone name="mKneeLeft" scale="0 0 -.05" /> + + <bone + name="mHindLimbsRoot" + scale="0 0 .1" /> + + <bone + name="mHindLimb1Left" + scale="0 0 -.1" /> + + <bone + name="mHindLimb1Right" + scale="0 0 -.1" /> + + <bone + name="mHindLimb2Right" + scale="0 0 -.05" /> + + <bone + name="mHindLimb2Left" + scale="0 0 -.05" /> </param_skeleton> </param> @@ -774,6 +1237,78 @@ name="mEyeRight" scale="0 0 0" offset="0 -.009 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0 .005 0" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0 -.005 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0 " + offset="0 .008 0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0 " + offset="0 -.008 0" /> + </param_skeleton> </param> @@ -797,32 +1332,183 @@ name="mEyeRight" scale="0 0 0" offset="0 0 -.004" /> - </param_skeleton> - </param> - <param - id="772" - group="1" - name="EyeBone_Head_Elongate" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Short Head" - label_max="Eyes Long Head" - value_min="-1" - value_max="1"> - <param_skeleton> - <bone - name="mEyeLeft" + <bone + name="mFaceEyeAltLeft" scale="0 0 0" - offset=".016 0 0" /> + offset="0 0 .004" /> - <bone - name="mEyeRight" + <bone + name="mFaceEyeAltRight" scale="0 0 0" - offset=".016 0 0" /> - </param_skeleton> - </param> + offset="0 0 -.004" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEar1Left" + scale="0 0 0" + offset="0 0 .004" /> + <bone + name="mFaceEar1Right" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipUpperLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceLipUpperRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipLowerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceLipLowerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipCornerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipCornerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0 0.004" /> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0" + offset="0 0 -.004" /> + + </param_skeleton> + </param> + + <param + id="772" + group="1" + name="EyeBone_Head_Elongate" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Short Head" + label_max="Eyes Long Head" + value_min="-1" + value_max="1"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset=".016 0 0" /> + <bone + name="mEyeRight" + scale="0 0 0" + offset=".016 0 0" /> + + </param_skeleton> + </param> + <param id="768" group="1" @@ -843,6 +1529,80 @@ name="mEyeRight" scale="0 0 0" offset=".005 0 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset=".002 0 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset=".002 0 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset=".001 0 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset=".001 0 0" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset=".0013 0 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset=".0013 0 0" /> + + + + </param_skeleton> </param> @@ -850,7 +1610,7 @@ id="655" group="1" name="Head Size" - label="Head Size" + label="Head Size" wearable="shape" edit_group="shape_head" label_min="Small Head" @@ -859,6 +1619,36 @@ value_min="-.25" value_max=".10"> <param_skeleton> + + <bone + name = "mFaceTeethLower" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceTeethUpper" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceEyecornerInnerLeft" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceEyecornerInnerRight" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceNoseBridge" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceNoseBase" + scale = "1 1 1" + offset = "0 0 0" /> <bone name="mSkull" scale="1 1 1" @@ -869,6 +1659,11 @@ scale="1 1 1" offset="0 0 0" /> + <bone + name="mFaceRoot" + scale="1 1 1" + offset="0 0 0" /> + <bone name="mEyeLeft" scale="1 1 1" @@ -878,2485 +1673,4274 @@ name="mEyeRight" scale="1 1 1" offset="0 0 0" /> - </param_skeleton> - </param> - - <param - id="197" - group="1" - wearable="shoes" - name="Shoe_Heels" - edit_group="shoes" - label_min="No Heels" - label_max="High Heels" - value_min="0" - value_max="1"> - <param_skeleton> + <bone - name="mFootRight" - scale="0 0 0" - offset="0 0 -.08" /> + name="mFaceEyeAltLeft" + scale="1 1 1" + offset="0 0 -0.001" /> <bone - name="mFootLeft" - scale="0 0 0" - offset="0 0 -.08" /> - </param_skeleton> - </param> - - <param - id="502" - group="1" - wearable="shoes" - name="Shoe_Platform" - edit_group="shoes" - label_min="No Heels" - label_max="High Heels" - value_min="0" - value_max="1"> - <param_skeleton> + name="mFaceEyeAltRight" + scale="1 1 1" + offset="0 0 -0.001" /> + <bone - name="mFootRight" - scale="0 0 0" - offset="0 0 -.07" /> + name="mFaceForeheadLeft" + scale="1 1 1" + offset="0 0 0" /> <bone - name="mFootLeft" - scale="0 0 0" - offset="0 0 -.07" /> - </param_skeleton> - </param> + name="mFaceForeheadCenter" + scale="1 1 1" + offset="0 0 0" /> - <param - id="675" - group="0" - name="Hand Size" - wearable="shape" - edit_group="shape_torso" - edit_group_order="10" - label_min="Small Hands" - label_max="Large Hands" - value_min="-.3" - value_max=".3" - camera_elevation=".1" - camera_distance="1.4" - camera_angle="0"> - <param_skeleton> <bone - name="mWristRight" + name="mFaceForeheadRight" scale="1 1 1" offset="0 0 0" /> <bone - name="mWristLeft" + name="mFaceEyebrowOuterLeft" scale="1 1 1" offset="0 0 0" /> - </param_skeleton> - </param> - <param - id="683" - group="0" - name="Neck Thickness" - wearable="shape" - edit_group="shape_torso" - edit_group_order="2" - label_min="Skinny Neck" - label_max="Thick Neck" - value_min="-.4" - value_max=".2" - value_default="-.15" - camera_elevation=".3" - camera_distance=".8" - camera_angle="15"> - <param_skeleton> <bone - name="mNeck" - scale="1 1 0" + name="mFaceEyebrowCenterLeft" + scale="1 1 1" offset="0 0 0" /> - </param_skeleton> - </param> - <param - id="689" - group="1" - wearable="shape" - name="EyeBone_Big_Eyes" - edit_group="shape_eyes" - label_min="Eyes Back" - label_max="Eyes Forward" - value_min="-1" - value_max="1"> - <param_skeleton> <bone - name="mEyeLeft" - scale="0 0 0" - offset="-.005 0 0" /> + name="mFaceEyebrowInnerLeft" + scale="1 1 1" + offset="0 0 0" /> <bone - name="mEyeRight" - scale="0 0 0" - offset="-.005 0 0" /> - </param_skeleton> - </param> - - <param - id="692" - group="0" - name="Leg Length" - wearable="shape" - edit_group="shape_legs" - edit_group_order="2" - label_min="Short Legs" - label_max="Long Legs" - value_min="-1" - value_max="1" - camera_distance="2.5"> + name="mFaceEyebrowOuterRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceNoseLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceNoseCenter" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceNoseRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekLowerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekUpperLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekLowerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekUpperRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceTongueBase" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceTongueTip" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceJaw" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceJawShaper" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceChin" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipUpperLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipUpperCenter" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipUpperRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipCornerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipCornerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipLowerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipLowerCenter" + scale="1 1 1" + offset="0 0 0" /> + <bone + name="mFaceLipLowerRight" + scale="1 1 1" + offset="0 0 0" /> + + </param_skeleton> + </param> + + <param + id="197" + group="1" + wearable="shoes" + name="Shoe_Heels" + edit_group="shoes" + label_min="No Heels" + label_max="High Heels" + value_min="0" + value_max="1"> <param_skeleton> <bone - name="mHipLeft" - scale="0 0 .2" /> + name="mFootRight" + scale="0 0 0" + offset="0 0 -.08" /> <bone - name="mHipRight" - scale="0 0 .2" /> + name="mFootLeft" + scale="0 0 0" + offset="0 0 -.08" /> <bone - name="mKneeRight" - scale="0 0 .2" /> + name="mHindLimb4Left" + scale="0 0 0" + offset="0 0 -.08" /> <bone - name="mKneeLeft" - scale="0 0 .2" /> + name="mHindLimb4Right" + scale="0 0 0" + offset="0 0 -.08" /> + </param_skeleton> </param> <param - id="693" + id="502" + group="1" + wearable="shoes" + name="Shoe_Platform" + edit_group="shoes" + label_min="No Heels" + label_max="High Heels" + value_min="0" + value_max="1"> + <param_skeleton> + <bone + name="mFootRight" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mFootLeft" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mHindLimb4Left" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mHindLimb4Right" + scale="0 0 0" + offset="0 0 -.07" /> + + </param_skeleton> + </param> + + <param + id="675" group="0" - name="Arm Length" + name="Hand Size" wearable="shape" edit_group="shape_torso" - edit_group_order="9" - label_min="Short Arms" - label_max="Long arms" - value_min="-1" - value_max="1" - value_default=".6" - camera_distance="1.5"> + edit_group_order="10" + label_min="Small Hands" + label_max="Large Hands" + value_min="-.3" + value_max=".3" + camera_elevation=".1" + camera_distance="1.4" + camera_angle="0"> <param_skeleton> <bone - name="mShoulderLeft" - scale="0 .2 0" /> + name="mWristRight" + scale="1 1 1" + offset="0 0 0" /> <bone - name="mShoulderRight" - scale="0 .2 0" /> + name="mWristLeft" + scale="1 1 1" + offset="0 0 0" /> - <bone - name="mElbowRight" - scale="0 .3 0" /> + <bone name = "mHandThumb1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandIndex1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandMiddle1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandRing1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandPinky1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandThumb1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandIndex1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandMiddle1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandRing1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandPinky1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky3Left" scale = "1 1 1" offset = "0 0 0" /> - <bone - name="mElbowLeft" - scale="0 .3 0" /> </param_skeleton> </param> <param - id="756" + id="683" group="0" - name="Neck Length" + name="Neck Thickness" wearable="shape" edit_group="shape_torso" - edit_group_order="3" - label_min="Short Neck" - label_max="Long Neck" - value_min="-1" - value_max="1" - value_default="0" + edit_group_order="2" + label_min="Skinny Neck" + label_max="Thick Neck" + value_min="-.4" + value_max=".2" + value_default="-.15" camera_elevation=".3" camera_distance=".8" camera_angle="15"> <param_skeleton> <bone name="mNeck" - scale="0 0 .5" /> + scale="1 1 0" + offset="0 0 0" /> </param_skeleton> - </param> - <param - id="11001" - group="0" - name="Hover" - wearable="shape" - edit_group="shape_body" - edit_group_order="4" - label_min="Lower" - label_max="Higher" - value_min="-2" - value_max="2" - value_default="0" - camera_distance="2.5"> - <param_skeleton /> </param> - </skeleton> - - <mesh - type="hairMesh" - lod="0" - file_name="avatar_hair.llm" - min_pixel_width="320"> - <!-- begin morph targets --> <param - id="180" + id="689" group="1" - name="Hair_Volume" - label="Hair Volume" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - label_min="Less" - label_max="More" - value_min="0" - value_max="1.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + wearable="shape" + name="EyeBone_Big_Eyes" + edit_group="shape_eyes" + label_min="Eyes Back" + label_max="Eyes Forward" + value_min="-1" + value_max="1"> + <param_skeleton> + + <bone + name="mEyeLeft" + scale="0 0 0" + offset="-.005 0 0" /> - <param - id="761" - group="1" - name="Hair_Volume_Small" - label="Hair Volume" - show_simple="true" - wearable="hair" - edit_group="hair_style" - label_min="Less" - label_max="More" - value_min="0" - value_max="1.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + <bone + name="mEyeRight" + scale="0 0 0" + offset="-.005 0 0" /> + + +<bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="-.005 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="-.005 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0.3 0.7" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0.3 0.7" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0.3 0.7" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0.3 0.7" + offset=" 0 0 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="-0.005 -0.008 0.0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="-0.005 0.008 0.0" /> + + </param_skeleton> </param> <param - id="181" + id="692" group="0" - name="Hair_Big_Front" - label="Big Hair Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="5" - label_min="Less" - label_max="More" + name="Leg Length" + wearable="shape" + edit_group="shape_legs" + edit_group_order="2" + label_min="Short Legs" + label_max="Long Legs" value_min="-1" value_max="1" - value_default="0.14" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + camera_distance="2.5"> + <param_skeleton> + <bone + name="mHipLeft" + scale="0 0 .2" /> + + <bone + name="mHipRight" + scale="0 0 .2" /> + + <bone + name="mKneeRight" + scale="0 0 .2" /> + + <bone + name="mKneeLeft" + scale="0 0 .2" /> + + <bone + name="mHindLimb1Left" + scale="0 0 .2" /> + + <bone + name="mHindLimb1Right" + scale="0 0 .2" /> + + <bone + name="mHindLimb2Right" + scale="0 0 .2" /> + + <bone + name="mHindLimb2Left" + scale="0 0 .2" /> + </param_skeleton> </param> <param - id="182" + id="693" group="0" - name="Hair_Big_Top" - label="Big Hair Top" - wearable="hair" - edit_group="hair_style" - edit_group_order="6" - label_min="Less" - label_max="More" + name="Arm Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="9" + label_min="Short Arms" + label_max="Long arms" value_min="-1" value_max="1" - value_default=".7" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + value_default=".6" + camera_distance="1.5"> + <param_skeleton> + <bone + name="mShoulderLeft" + scale="0 .2 0" /> + + <bone + name="mShoulderRight" + scale="0 .2 0" /> + + <bone + name="mElbowRight" + scale="0 .3 0" /> + + <bone + name="mElbowLeft" + scale="0 .3 0" /> + </param_skeleton> </param> <param - id="183" + id="756" group="0" - name="Hair_Big_Back" - clothing_morph="true" - label="Big Hair Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="7" - label_min="Less" - label_max="More" + name="Neck Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="3" + label_min="Short Neck" + label_max="Long Neck" value_min="-1" value_max="1" - value_default="0.05" - camera_elevation=".1" - camera_distance=".7" - camera_angle="90"> - <param_morph /> + value_default="0" + camera_elevation=".3" + camera_distance=".8" + camera_angle="15"> + <param_skeleton> + <bone + name="mNeck" + scale="0 0 .5" /> + </param_skeleton> </param> - + <param - id="184" + id="11001" group="0" - name="Hair_Spiked" - label="Spiked Hair" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - edit_group_order="15" - label_min="No Spikes" - label_max="Big Spikes" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + name="Hover" + wearable="shape" + edit_group="shape_body" + edit_group_order="4" + label_min="Lower" + label_max="Higher" + value_min="-2" + value_max="2" + value_default="0" + camera_distance="2.5"> + <param_skeleton /> </param> + + <param + id="30002" + group="1" + name="Nose_Big_Out" + value_min="-0.8" + value_max="2.5"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0.0 0.0 0.0" + scale = "0.50 0.3 0.1" /> + <bone + name = "mFaceNoseLeft" + offset = "0 0 0" + scale = "0.0 0.3 0.0" /> + <bone + name = "mFaceNoseRight" + offset = "0 0 0" + scale = "0.0 0.3 0.0" /> + <bone + name = "mFaceNoseBridge" + offset = "0.006 0.0 0.0" + scale = "0.10 0.1 0.0" /> + </param_skeleton> + </param> + <param - id="140" - group="0" - name="Hair_Part_Middle" - label="Middle Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="17" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + id="30004" + group="1" + name="Broad_Nostrils" + value_min="-.5" + value_max="1"> + <param_skeleton> + <bone + name = "mFaceNoseLeft" + offset = "0 0.005 0" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceNoseRight" + offset = "0 -0.005 0" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + <param - id="141" - group="0" - name="Hair_Part_Right" - label="Right Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="18" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + id="30020" + group="1" + name="Bulbous_Nose" + value_min="-.5" + value_max="1.5" + > + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0.0 0.0 0.0" + scale = "0.2 0.4 0.2" /> + <bone + name = "mFaceNoseLeft" + scale = "0 0.3 0" + offset = "0 0.0015 0" + /> + <bone + name = "mFaceNoseRight" + scale = "0 0.3 0" + offset = "0 -0.0015 0" + /> + + </param_skeleton> + </param> <param - id="142" - group="0" - name="Hair_Part_Left" - label="Left Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="19" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + id="30517" + group="1" + name="Wide_Nose" + value_min="-.5" + value_max="1"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0 0 0" + scale = "0.10 0.85 0.0" /> + <bone + name = "mFaceNoseLeft" + scale = "0 0 0" + offset = "0.001 0.013 0"/> + <bone + name = "mFaceNoseRight" + scale = "0 0 0" + offset = "0.001 -0.013 0" /> + </param_skeleton> </param> <param - id="143" - group="0" - name="Hair_Sides_Full" - label="Full Hair Sides" - show_simple="true" - wearable="hair" - edit_group="hair_style" - edit_group_order="11" - label_min="Mowhawk" - label_max="Full Sides" - value_min="-4" - value_max="1.5" - value_default="0.125" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + id="30656" + group="1" + name="Crooked_Nose" + value_min="-2" + value_max="2"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 0.009 0.0" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0.0 0.007 0.0" /> + + <bone + name = "mFaceNoseLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.005 0.0"/> + + <bone + name = "mFaceNoseRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.005 0.0" /> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.002 0.0" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.002 0.0" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + + <bone + name = "mFaceEyebrowInnerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.0008 0.0" /> + + <bone + name = "mFaceEyebrowInnerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.0008 0.0" /> + + <bone + name = "mFaceNoseBridge" + scale = "0.0 0.00 0.0" + offset = "0.0 0.004 0.0" /> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceEyecornerInnerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + + <bone + name = "mFaceEyecornerInnerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + </param_skeleton> + </param> + <param - id="144" + id="30155" group="1" - name="Bangs_Front_Up" - label="Front Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Bangs" - label_max="Bangs Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + name="Lip Width" + value_min="-0.9" + value_max="1.3" + value_default="0"> + <param_skeleton> + <bone + name = "mFaceLipCornerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.005 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.005 0.0" /> + + </param_skeleton> </param> <param - id="145" + id="30653" group="1" - clothing_morph="true" - name="Bangs_Front_Down" - label="Front Bangs Down" - wearable="hair" - edit_group="hair_style" - label_min="Bangs" - label_max="Bangs Down" - value_min="0" - value_max="5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + name="Tall_Lips" + value_min="-1" + value_max="2"> + <param_skeleton> + <bone + name = "mFaceLipCornerLeft" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.2 0.00 0.2" + offset = "-0.009 0.00 0.0025" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.2 0.00 0.2" + offset = "-0.009 0.00 0.0025" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.2 0.00 0.2" + offset = "-0.009 0.00 0.0025" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 -0.0015" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 -0.0025" /> + <bone + name = "mFaceLipLowerRight" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 -0.0015" /> + + </param_skeleton> + </param> + <param - id="146" + id="30505" group="1" - name="Bangs_Sides_Up" - label="Side Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Side Bangs" - label_max="Side Bangs Up" + name="Lip_Thickness" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + value_max="0.7"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.2 0.00 -0.6" + offset = "-0.012 0.00 -0.005" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.2 0.00 -0.6" + offset = "-0.015 0.00 -0.005" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.2 0.00 -0.6" + offset = "-0.012 0.00 -0.005" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.008" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.008" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.008" /> + </param_skeleton> + </param> + <param - id="147" + id="31505" group="1" - clothing_morph="true" - name="Bangs_Sides_Down" - label="Side Bangs Down" - wearable="hair" - edit_group="hair_style" - label_min="Side Bangs" - label_max="Side Bangs Down" + name="Lip_Thickness" value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + value_max="1"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.2 0.00 0.1" + offset = "0.005 0.00 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.2 0.00 0.4" + offset = "0.004 0.00 0.004" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.2 0.00 0.4" + offset = "0.004 0.00 0.004" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.2 0.00 0.4" + offset = "0.004 0.00 0.004" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.2 0.00 0.1" + offset = "0.005 0.00 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.2 0.00 0.3" + offset = "0.006 0.00 -0.003" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0.2 0.00 0.3" + offset = "0.006 0.00 -0.003" /> + <bone + name = "mFaceLipLowerRight" + scale = "0.2 0.00 0.3" + offset = "0.006 0.00 -0.003" /> + + </param_skeleton> + </param> + <param - id="148" + id="30797" group="1" - name="Bangs_Back_Up" - label="Back Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Back Bangs" - label_max="Back Bangs Up" + name="Fat_Upper_Lip" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + value_max="1.5"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipUpperLeft" + scale = " 0.1 0 0.6" + offset = "-0.004 0.00 0.006" /> + + <bone + name = "mFaceLipUpperCenter" + scale = " 0.1 0 0.4" + offset = "-0.004 0.00 0.003" /> + + <bone + name = "mFaceLipUpperRight" + scale = " 0.1 0 0.6" + offset = "-0.004 0.00 0.006" /> + + <bone + name = "mFaceLipLowerLeft" + scale = " 0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipLowerCenter" + scale = " 0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipLowerRight" + scale = " 0 0 0" + offset = "-0.002 0.00 0.001" /> + + </param_skeleton> </param> <param - id="149" + id="30798" group="1" - name="Bangs_Back_Down" - label="Back Bangs Down" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - label_min="Back Bangs" - label_max="Back Bangs Down" + name="Fat_Lower_Lip" value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + value_max="1.5"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "-0.002 0.00 -0.002" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "-0.002 0.00 -0.002" /> + + <bone + name = "mFaceLipUpperLeft" + scale = " 0 0 0" + offset = "-0.002 0.00 -0.003" /> + + <bone + name = "mFaceLipUpperCenter" + scale = " 0 0 0" + offset = "-0.002 0.00 -0.003" /> + + <bone + name = "mFaceLipUpperRight" + scale = " 0 0 0" + offset = "-0.002 0.00 -0.003" /> + + <bone + name = "mFaceLipLowerLeft" + scale = " 0.1 0 0.25" + offset = "-0.005 0.00 -0.004" /> + + <bone + name = "mFaceLipLowerCenter" + scale = " 0.1 0 0.25" + offset = "-0.005 0.00 -0.004" /> + + <bone + name = "mFaceLipLowerRight" + scale = " 0.1 0 0.25" + offset = "-0.005 0.00 -0.004" /> + + </param_skeleton> </param> + + <param + id="30506" + group="1" + name="Mouth_Height" + value_min="-2" + value_max="2"> + <param_skeleton> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0 0 -0.006" /> + + <bone + name = "mFaceTeethLower" + scale = "0.0 0.00 0.0" + offset = "0 0 -0.006" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0 0 -0.001" /> + </param_skeleton> + </param> + <param - id="171" + id="30658" group="1" - name="Hair_Front_Down" - label="Front Hair Down" - wearable="hair" - edit_group="hair_style" - label_min="Front Hair" - label_max="Front Hair Down" + name="Frown_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="1.4"> + <param_skeleton> + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "0 0 -0.005" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "0 0 -0.005" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0 0" + offset = "0 0 0" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0 0 0" + offset = "0 0 0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0 0" + offset = "0 0 0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0 0 0" + offset = "0 0 0.001" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0 0 0" + offset = "0 0 0.002" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0 0 0" + offset = "0 0 0.001" /> + </param_skeleton> </param> <param - id="172" + id="30657" group="1" - name="Hair_Front_Up" - label="Front Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Front Hair" - label_max="Front Hair Up" + name="Smile_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="1.4"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "0 0.005 0.002" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "0 -0.005 0.002" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0 0" + offset = "0 0.002 0" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0 0 0" + offset = "0 0 -0.0005" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0 0" + offset = "0 -0.002 0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0 0 0" + offset = "0 0.001 0" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0 0 0" + offset = "0 0 -0.001" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0 0 0" + offset = "0 -0.001 0" /> + + </param_skeleton> </param> + +<param + id="30764" + group="1" + name="Lip_Cleft_Deep" + value_min="-1" + value_max="1.2"> + <param_skeleton> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0 0.3" + offset = "0 0 0.003" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0 0 -0.1" + offset = "0 0 -0.001" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0 0.3" + offset = "0 0 0.003" /> + + </param_skeleton> + </param> + +<param + id="30025" + group="1" + name="Wide_Lip_Cleft" + value_min="-.8" + value_max="1.5"> + <param_skeleton> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0.1 0" + offset = "0 0.0 0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0.1 0" + offset = "0 0.0 0" /> + <bone + name = "mFaceLipCornerRight" + scale = "0.0 0 0" + offset = "0 0.001 0" /> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.0 0 0" + offset = "0 -0.001 0" /> + + </param_skeleton> + </param> + <param - id="173" + id="31663" group="1" - name="Hair_Sides_Down" - label="Sides Hair Down" - wearable="hair" - edit_group="hair_style" - label_min="Sides Hair" - label_max="Sides Hair Down" + name="Shift_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="2"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.004 0.0" /> + + <bone + name = "mFaceNoseLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0"/> + + <bone + name = "mFaceNoseRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.006 0.0" /> + + <bone + name = "mFaceTeethLower" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.006 0.0" /> + + + + </param_skeleton> </param> <param - id="174" + id="32663" group="1" - name="Hair_Sides_Up" - label="Sides Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Sides Hair" - label_max="Sides Hair Up" + name="Shift_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + value_max="2"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0.0 0.004 0.0" /> + + <bone + name = "mFaceNoseLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0"/> + + <bone + name = "mFaceNoseRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0.0 0.006 0.0" /> + + <bone + name = "mFaceTeethLower" + scale = "0.0 0.00 0.0" + offset = "0.0 0.006 0.0" /> + + + </param_skeleton> + </param> <param - id="175" + id="30035" group="1" - name="Hair_Back_Down" - label="Back Hair Down" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - label_min="Back Hair" - label_max="Back Hair Down" - value_min="0" - value_max="3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + name="Big_Ears" + value_min="-1" + value_max="2"> + <param_skeleton> + <bone + name = "mFaceEar1Left" + scale = "0.55 0.55 0.55" + offset = "0.0 -0.002 0.001" /> + <bone + name = "mFaceEar1Right" + scale = "0.55 0.55 0.55" + offset = "0.0 0.002 0.001" /> + </param_skeleton> </param> - + <param - id="176" + id="30015" group="1" - name="Hair_Back_Up" - label="Back Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Back Hair" - label_max="Back Hair Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + name="Ears_Out" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + <!-- Place Holder. Can't do this unless we get rotation offset --> + <bone + name = "mFaceEar1Left" + offset = "0.0 -0.0 0.0" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceEar1Right" + offset = "0.0 0.0 0.0" + scale = "0.0 0.0 0.0" /> + </param_skeleton> + </param> + + <param + id="30796" + group="1" + name="Pointy_Ears" + value_min="-.4" + value_max="3"> + <param_skeleton> + <bone + name = "mFaceEar2Left" + offset = "-0.0149 0.001 0.016" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceEar2Right" + offset = "-0.0149 -0.001 0.016" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + <param - id="177" - group="0" - name="Hair_Rumpled" - label="Rumpled Hair" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - edit_group_order="14.5" - label_min="Smooth Hair" - label_max="Rumpled Hair" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + id="30185" + group="1" + name="Deep_Chin" + value_min="-1" + value_max="1"> + <!-- used for the chin depth slider --> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "0.0 0.00 -0.025" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - <param - id="178" + id="40185" group="1" - name="Hair_Swept_Back" - label="Swept Back Hair" - wearable="hair" - edit_group="hair_style" - label_min="NotHair" - label_max="Swept Back" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + name="Deep_Chin" + value_min="-1" + value_max="1"> + <!-- used for the head shape slider --> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "0.0 0.00 -0.02" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + <param - id="179" + id="30760" group="1" - name="Hair_Swept_Forward" - label="Swept Forward Hair" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Swept Forward" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + name="Jaw_Angle" + value_min="-1.2" + value_max="2" + value_default="0"> + <param_skeleton> + <bone + name = "mFaceJawShaper" + offset = "0.0 0.00 0.03" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + + <param - id="190" + id="30665" group="1" - name="Hair_Tilt_Right" - label="Hair Tilted Right" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Tilt Right" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + name="Jaw_Jut" + value_min="-2" + value_max="2"> + <param_skeleton> + + <bone + name = "mFaceTeethLower" + offset = "0.008 0 0" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceChin" + offset = "0.008 0.00 0" + scale = "0.0 0.0 0.0" /> + + </param_skeleton> + </param> + <param - id="191" + id="30006" group="1" - name="Hair_Tilt_Left" - label="Hair Tilted Left" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Tilt Left" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + name="Bulbous_Nose_Tip" + value_min="-1" + value_max="1.5"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0.0 0.00 0.0" + scale = "0.1 0.1 0.1" /> + + </param_skeleton> </param> - + <param - id="192" - group="0" - name="Bangs_Part_Middle" - label="Part Bangs" - wearable="hair" - edit_group="hair_style" - edit_group_order="20" - label_min="No Part" - label_max="Part Bangs" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + id="30007" + group="1" + name="Weak_Chin" + value_min="-.5" + value_max=".5"> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "-0.06 0.00 0.01" + scale = "0.0 0.0 0.0" /> + + </param_skeleton> + </param> + + <param + id="40007" + group="1" + name="Weak_Chin" + value_min="-.5" + value_max=".5"> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "-0.025 0.00 0.005" + scale = "0.0 0.0 0.0" /> + + </param_skeleton> + </param> + + <param + id="30008" + group="1" + name="Double_Chin" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + <bone + name = "mFaceJawShaper" + offset = "0 0 0" + scale = "0.0 0.125 0.5" /> + </param_skeleton> </param> + + + <param + id="30024" + group="1" + name="Wide_Eyes" + value_min="-1.5" + value_max="2"> + <param_skeleton> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0 0 0" /> + </param_skeleton> + </param> + <param - id="640" + id="30650" group="1" - name="Hair_Egg_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Eyelid_Corner_Up" value_min="-1.3" - value_max="1"> - <param_morph /> + value_max="1.2"> + <param_skeleton> + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 0 .004" /> + </param_skeleton> </param> + + <param + id="30880" + group="1" + name="Eyelid_Inner_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_skeleton> + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0 .004" /> + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 0 .004" /> + </param_skeleton> + </param> + <param - id="641" + id="30765" group="1" - name="Hair_Squash_Stretch_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" - value_min="-.5" - value_max="1"> - <param_morph /> + name="Puffy_Lower_Lids" + value_min="-.3" + value_max="2.5"> + <param_skeleton> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + </param_skeleton> </param> <param - id="642" + id="31629" group="1" - name="Hair_Square_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.08" + offset="0.02 0 0" /> + + <bone + name="mFaceForeheadCenter" + scale="0.01 0 0.08" + offset="0.002 0 0" /> + <bone + name="mFaceForeheadRight" + scale="0 0 0.08" + offset="0.02 0 0" /> + + </param_skeleton> + </param> + <param - id="643" + id="41629" group="1" - name="Hair_Round_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.08" + offset="0.02 0 0" /> + + <bone + name="mFaceForeheadCenter" + scale="0.01 0 0.08" + offset="0.002 0 0" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.08" + offset="0.02 0 0" /> + + </param_skeleton> + </param> + + <param + id="30647" + group="1" + name="Squash_Stretch_Head" + value_min="-0.5" + value_max="1" + value_default="0"> + <param_skeleton> + + <bone + name="mFaceRoot" + scale="0 -0.1 0.1" + offset="0 0 0" /> + + <bone + name="mFaceChin" + scale="0 -0.1 0.5" + offset="0 0 -0.005" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="0 0 -0.006" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 -0.0053 -0.0047" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 -0.0045 -0.0053" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 -0.00225 -0.0048" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0.0053 -0.0047" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0.0045 -0.0053" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0.00225 -0.0048" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0 -0.0042 -0.0035" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0 0.0042 -0.0035" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 -0.0039 -0.0032" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0.0039 -0.0032" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="0 -0.0039 -0.0032" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="0 0.0039 -0.0032" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 -0.00225 -0.0032" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0.00225 -0.0032" /> + + <bone + name="mFaceNoseBridge" + scale="0 0 0" + offset="0 0 -0.002" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0 -0.002 0" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0 0.002 0" /> + + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 -0.003 0" /> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0.003 0" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0 -0.003 0.0032" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0 0.003 0.0032" /> + + <bone + name="mFaceTeethUpper" + scale="0 0 0" + offset="0 0 0.0032" /> + <bone + name="mFaceTeethLower" + scale="0 0 0" + offset="0 0 0.0016" /> + + </param_skeleton> </param> <param - id="644" + id="32629" group="1" - name="Hair_Forehead_Round" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="-0.001 0 0.001" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 0 0.003" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0 0.003" /> + + </param_skeleton> </param> <param - id="645" + id="42629" group="1" - name="Hair_Forehead_Slant" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="-0.001 0 0.001" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 0 0.003" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0 0.003" /> + + </param_skeleton> </param> <param - id="774" + id="30001" group="1" - name="Shear_Head_Hair" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" - value_min="-2" + name="Big_Brow" + value_min="-.3" value_max="2"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="0.007 0 0.001" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0.004 0 0" /> + </param_skeleton> + </param> + <param - id="771" + id="30011" group="1" - name="Elongate_Head_Hair" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" - value_min="-1" - value_max="1"> - <param_morph /> + name="Noble_Nose_Bridge" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + + <bone + name="mFaceNoseBridge" + scale="0.15 0.01 0.7" + offset="0.009 0 -0.006" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="0.001 0 0" /> + + </param_skeleton> </param> <param - id="674" - group="0" - name="Hair_Shear_Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="12" - label="Shear Back" - label_min="Full Back" - label_max="Sheared Back" - value_min="-1" - value_max="2" - value_default="-0.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="100"> - <param_morph /> + id="30758" + group="1" + name="Lower_Bridge_Nose" + value_min="-1.5" + value_max="1.5"> + <param_skeleton> + + <bone + name="mFaceNoseBridge" + scale="0 0 0.2" + offset="0.0025 0 -0.001" /> + + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset="0.004 0 0.001" /> + + </param_skeleton> </param> <param - id="762" - group="0" - name="Hair_Shear_Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="11.8" - label="Shear Front" - show_simple="true" - label_min="Full Front" - label_max="Sheared Front" - value_min="0" - value_max="3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="30"> - <param_morph /> - </param> + id="30027" + group="1" + name="Wide_Nose_Bridge" + value_min="-1.3" + value_max="1.2"> + <param_skeleton> + + <bone + name="mFaceNoseBridge" + scale="0 0.4 0" + offset="0 0 0" /> + </param_skeleton> + </param> + <param - id="754" - group="0" - name="Hair_Taper_Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="14" - label="Taper Back" - label_min="Wide Back" - label_max="Narrow Back" + id="30759" + group="1" + name="Low_Septum_Nose" value_min="-1" - value_max="2" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="160"> - <param_morph /> - </param> + value_max="1.5" + value_default="0.5"> + <param_skeleton> + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0 0 -0.004" /> + + </param_skeleton> + + </param> + + <param - id="755" - group="0" - name="Hair_Taper_Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="13" - label="Taper Front" - label_min="Wide Front" - label_max="Narrow Front" + id="30010" + group="1" + name="Sunken_Cheeks" value_min="-1.5" - value_max="1.5" - value_default="0.05" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="3"> + <param_skeleton> + + <bone + name="mFaceCheekLowerLeft" + scale="0 -0.12 0" + offset="0.0 0.0 0" /> + <bone + name="mFaceCheekLowerRight" + scale="0 -0.12 0" + offset="0 0 0" /> + + </param_skeleton> </param> <param - id="782" + id="30017" group="1" - clothing_morph="true" - name="Hair_Pigtails_Short" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="Square_Jaw" + value_min="-0.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceChin" + scale="0.0 0.5 0.0" + offset="0.0 0.0 0.0" /> + + </param_skeleton> + </param> <param - id="783" + id="40017" group="1" - clothing_morph="true" - name="Hair_Pigtails_Med" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="Square_Jaw" + value_min="-0.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> - <param - id="790" + <bone + name="mFaceJaw" + scale="0.0 0.5 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceJawShaper" + scale="0.0 0.5 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceLipLowerRight" + scale="0.0 0.0 0.0" + offset="0.0 0.0038 0.0" /> + + <bone + name="mFaceLipLowerLeft" + scale="0.0 0.0 0.0" + offset="0.0 -0.0038 0.0" /> + + </param_skeleton> + </param> + + + <param + id="30018" group="1" - clothing_morph="true" - name="Hair_Pigtails_Medlong" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> - </param> + name="Puffy_Upper_Cheeks" + value_min="-1.5" + value_max="2.5"> + <param_skeleton> + + <bone + name="mFaceCheekUpperLeft" + scale="0.15 0.1 0.1" + offset="0.002 0 0.0015" /> + + <bone + name="mFaceCheekUpperRight" + scale="0.15 0.1 0.1" + offset="0.002 0 0.0015" /> + </param_skeleton> + </param> + <param - id="784" + id="30021" group="1" - clothing_morph="true" - name="Hair_Pigtails_Long" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> + name="Upper_Eyelid_Fold" + value_min="-0.2" + value_max="1.3"> + <param_skeleton> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0 -.006" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 0 -.006" /> + + </param_skeleton> </param> <param - id="786" + id="30023" group="1" - name="Hair_Ponytail_Short" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> + name="Baggy_Eyes" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 .5" + offset="0 0 -.001" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 .5" + offset="0 0 -.001" /> + + </param_skeleton> </param> <param - id="787" + id="30014" group="1" - name="Hair_Ponytail_Med" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="High_Cheek_Bones" + value_min="-.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0 0.02" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 0 0.02" /> + </param_skeleton> + </param> + <param - id="788" + id="30019" group="1" - name="Hair_Ponytail_Long" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="Upturned_Nose_Tip" + value_min="-1.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> - <!-- #end morph targets --> - </mesh> + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0.001 0 -0.0015" /> - <mesh - type="hairMesh" - lod="1" - file_name="avatar_hair_1.llm" - min_pixel_width="160" - reference="avatar_hair.llm"> - </mesh> + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset="-0.002 0 0.004" /> - <mesh - type="hairMesh" - lod="2" - file_name="avatar_hair_2.llm" - min_pixel_width="80" - reference="avatar_hair.llm"> - </mesh> + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0.001 0 -0.002" /> - <mesh - type="hairMesh" - lod="3" - file_name="avatar_hair_3.llm" - min_pixel_width="40" - reference="avatar_hair.llm"> - </mesh> + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0.001 0 -0.002" /> - <mesh - type="hairMesh" - lod="4" - file_name="avatar_hair_4.llm" - min_pixel_width="20" - reference="avatar_hair.llm"> - </mesh> + </param_skeleton> + </param> + + <param + id="30879" + group="1" + sex="male" + name="Male_Package" + value_min="-.5" + value_max="2"> + <param_skeleton> - <mesh - type="hairMesh" - lod="5" - file_name="avatar_hair_5.llm" - min_pixel_width="0" - reference="avatar_hair.llm"> - </mesh> + <bone + name = "mGroin" + offset = "0.0 0.0 0.0" + scale = ".5 .25 .1" /> + + </param_skeleton> + </param> + + <param + id="30193" + group="1" + name="Square_Head" + value_min="-1" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceChin" + scale="0.0 -0.2 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceRoot" + scale="0.0 0 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceCheekLowerRight" + scale="0.0 -0.2 0.0" + offset="0.0 0 0.0" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0.0 -0.2 0.0" + offset="0.0 0 0.0" /> + + <bone + name="mFaceForeheadRight" + scale="0.0 -1.0 0.0" + offset="0.0 0.01 -0.01" /> + + <bone + name="mFaceForeheadLeft" + scale="0.0 -1.0 0.0" + offset="0.0 -0.01 -0.01" /> + + <bone + name="mFaceJawShaper" + scale="0.0 -0.3 0.0" + offset="0.0 0 0" /> + + </param_skeleton> + </param> + + <param + id="30646" + group="1" + name="Egg_Head" + value_min="-1.3" + value_max="1" + value_default="0"> + <param_skeleton> - <mesh - type="headMesh" - lod="0" - file_name="avatar_head.llm" - min_pixel_width="320"> - <!-- - begin morph targets - ############# - tweakable morphs - ############# - --> + <bone + name="mFaceRoot" + scale="0 -0.07 0.07" + offset="0 0 -0.005" /> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="-0.001 0 0.001" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name = "mFaceChin" + offset = "0.015 0.00 0.005" + scale = "0.0 0.0 0.0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0 -0.0033 0.0025" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0 0.0033 0.0025" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="0 -0.0033 0.0025" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 -0.0033 0.002" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 -0.0017 0.0025" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 -0.004 0.0014" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 -0.00377 0.00061" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 -0.00225 0.001" /> + + + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="0 0.0033 0.0025" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0.0033 0.002" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0.0017 0.0025" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0.004 0.0014" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0.00377 0.00061" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0.00225 0.001" /> + + <bone + name="mFaceLipLowerRight" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mFaceLipLowerCenter" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mFaceLipLowerLeft" + scale="0 0 0" + offset="0 0 0" /> + + <bone + name="mFaceTeethUpper" + scale="0 0 0" + offset="0 0 0.0075" /> + + <bone + name="mFaceTeethLower" + scale="0 0 0" + offset="0 0 0.0061" /> + + <bone + name="mFaceTongueBase" + scale="0 0 0" + offset="0 0 -0.00" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0 0 0.0085" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0 0 0.0085" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0 0 0.006" /> + + <bone + name="mFaceJawShaper" + scale="0 0.2 0" + offset="0 0 0" /> + + </param_skeleton> + </param> + <param - id="1" - group="0" - name="Big_Brow" - label="Brow Size" - wearable="shape" - edit_group="shape_head" - edit_group_order="7" - label_min="Small" - label_max="Large" - value_min="-.3" - value_max="2" - camera_elevation=".1" - camera_distance=".4" - camera_angle="45"> - <param_morph /> + id="30689" + group="1" + name="EyeBone_Big_Eyes" + value_min="-1.1" + value_max="1.1"> + <param_skeleton> + + <!-- Experimental: Added Scale to the System eyes. From first look this affects only custom meshes. + | The result is: Custom eyes now scale in the same way as system eyes do + | Revert by setting scale to scale="0 0 0" for mEyeLeft and mEyeRight + --> + <bone + name="mEyeLeft" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + <bone + name="mEyeRight" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + </param_skeleton> </param> <param - id="2" - group="0" - name="Nose_Big_Out" - label="Nose Size" - wearable="shape" - edit_group="shape_nose" - edit_group_order="1" - label_min="Small" - label_max="Large" - show_simple="true" - value_min="-0.8" - value_max="2.5" - camera_elevation=".1" - camera_distance=".35" - camera_angle="50"> - <param_morph /> + id="30772" + group="1" + name="EyeBone_Head_Elongate" + value_min="-1" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceRoot" + scale="0.25 0 0" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset=".01 0 0" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceLipUpperLeft" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipUpperCenter" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipUpperRight" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipCornerRight" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipCornerLeft" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipLowerLeft" + scale="0 0 0" + offset="0.01 0 0" /> + + <bone + name="mFaceLipLowerCenter" + scale="0 0 0" + offset="0.01 0 0" /> + + <bone + name="mFaceLipLowerRight" + scale="0 0 0" + offset="0.01 0 0" /> + + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0.007 0 0" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0.007 0 0" /> + + <bone + name="mFaceChin" + scale="0 0 0" + offset="0.014 0 0" /> + + <bone + name="mFaceTeethUpper" + scale="0.28 0 0" + offset="0 0 0" /> + <bone + name="mFaceTeethLower" + scale="0.28 0 0" + offset="0 0 0" /> + + <bone + name="mFaceTongueBase" + scale="0.3 0 0" + offset="0 0 0" /> + + <bone + name="mFaceTongueTip" + scale="0 0 0" + offset="0.004 0 0" /> + + </param_skeleton> </param> + + <param + id="31772" + group="1" + name="EyeBone_Head_Elongate" + value_min="0" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0.0058 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0.0058 0 0" /> + </param_skeleton> + </param> + <param - id="4" - group="0" - name="Broad_Nostrils" - label="Nostril Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="3" - label_min="Narrow" - label_max="Broad" - value_min="-.5" + id="32772" + group="1" + name="EyeBone_Head_Elongate" + value_min="0" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="-0.0032 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="-0.0032 0 0" /> + + </param_skeleton> + </param> + + + <!-- Eye Brow sliders --> + + <param + id="30119" + group="1" + name="Eyebrow Size" + value_min="0" value_max="1" + value_default="0.5"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0.5" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0.5" + offset="0 0 0" /> + + </param_skeleton> + </param> + + <param + id="30031" + group="1" + name="Arced_Eyebrows" + value_min="0" + value_max="2" + value_default=".5"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0.0 0.0 0.005" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0.0 0.0 0.001" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0.0 0.0 0.005" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0.0 0.0 0.001" /> + + </param_skeleton> + </param> + + <param + id="30757" + group="1" + name="Lower_Eyebrows" + value_min="-4" + value_max="2" + value_default="-1"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + </param_skeleton> + </param> + + <param + id="30016" + group="1" + name="Pointy_Eyebrows" + value_min="-.5" + value_max="3"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0.0 -0.001 0.0035" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0.0 0.001 0.0035" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + </param_skeleton> + </param> + + </skeleton> + + <mesh + type="hairMesh" + lod="0" + file_name="avatar_hair.llm" + min_pixel_width="320"> + <!-- begin morph targets --> + <param + id="180" + group="1" + name="Hair_Volume" + label="Hair Volume" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + label_min="Less" + label_max="More" + value_min="0" + value_max="1.3" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="759" - group="0" - name="Low_Septum_Nose" - label="Nostril Division" - wearable="shape" - edit_group="shape_nose" - edit_group_order="3.5" - label_min="High" - label_max="Low" - value_min="-1" - value_max="1.5" - value_default="0.5" + id="761" + group="1" + name="Hair_Volume_Small" + label="Hair Volume" + show_simple="true" + wearable="hair" + edit_group="hair_style" + label_min="Less" + label_max="More" + value_min="0" + value_max="1.3" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="517" + id="181" group="0" - name="Wide_Nose" - label="Nose Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="2" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-.5" + name="Hair_Big_Front" + label="Big Hair Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="5" + label_min="Less" + label_max="More" + value_min="-1" value_max="1" + value_default="0.14" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="5" + id="182" group="0" - name="Cleft_Chin" - label="Chin Cleft" - wearable="shape" - edit_group="shape_chin" + name="Hair_Big_Top" + label="Big Hair Top" + wearable="hair" + edit_group="hair_style" edit_group_order="6" - label_min="Round" - label_max="Cleft" - value_min="-.1" + label_min="Less" + label_max="More" + value_min="-1" value_max="1" - camera_elevation="0" - camera_distance=".28" - camera_angle="-20"> + value_default=".7" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="6" + id="183" group="0" - name="Bulbous_Nose_Tip" - label="Nose Tip Shape" - wearable="shape" - edit_group="shape_nose" - edit_group_order="8" - label_min="Pointy" - label_max="Bulbous" - value_min="-.3" + name="Hair_Big_Back" + clothing_morph="true" + label="Big Hair Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="7" + label_min="Less" + label_max="More" + value_min="-1" value_max="1" + value_default="0.05" camera_elevation=".1" - camera_distance=".35" - camera_angle="15"> + camera_distance=".7" + camera_angle="90"> <param_morph /> </param> <param - id="7" + id="184" group="0" - name="Weak_Chin" - label="Chin Angle" - wearable="shape" - edit_group="shape_chin" - edit_group_order="1" - label_min="Chin Out" - label_max="Chin In" - value_min="-.5" - value_max=".5" + name="Hair_Spiked" + label="Spiked Hair" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + edit_group_order="15" + label_min="No Spikes" + label_max="Big Spikes" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".4" - camera_angle="45"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="8" + id="140" group="0" - name="Double_Chin" - label="Chin-Neck" - wearable="shape" - edit_group="shape_chin" - edit_group_order="8" - label_min="Tight Chin" - label_max="Double Chin" - value_min="-.5" - value_max="1.5" - camera_elevation="-.1" - camera_distance=".3" - camera_angle="60"> + name="Hair_Part_Middle" + label="Middle Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="17" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="10" + id="141" group="0" - name="Sunken_Cheeks" - label="Lower Cheeks" - wearable="shape" - edit_group="shape_head" - edit_group_order="9" - label_min="Well-Fed" - label_max="Sunken" - show_simple="true" - value_min="-1.5" - value_max="3" + name="Hair_Part_Right" + label="Right Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="18" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".4" - camera_angle="5"> + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="11" + id="142" group="0" - name="Noble_Nose_Bridge" - label="Upper Bridge" - wearable="shape" - edit_group="shape_nose" - edit_group_order="5" - label_min="Low" - label_max="High" - value_min="-.5" - value_max="1.5" + name="Hair_Part_Left" + label="Left Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="19" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".35" - camera_angle="70"> + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="758" + id="143" group="0" - name="Lower_Bridge_Nose" - label="Lower Bridge" - wearable="shape" - edit_group="shape_nose" - edit_group_order="5.5" - label_min="Low" - label_max="High" - value_min="-1.5" + name="Hair_Sides_Full" + label="Full Hair Sides" + show_simple="true" + wearable="hair" + edit_group="hair_style" + edit_group_order="11" + label_min="Mowhawk" + label_max="Full Sides" + value_min="-4" value_max="1.5" + value_default="0.125" camera_elevation=".1" - camera_distance=".35" - camera_angle="70"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="12" - group="0" - name="Jowls" - wearable="shape" - edit_group="shape_chin" - edit_group_order="5" - label_min="Less" - label_max="More" - value_min="-.5" - value_max="2.5" + id="144" + group="1" + name="Bangs_Front_Up" + label="Front Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Bangs" + label_max="Bangs Up" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".4" - camera_angle="0"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="13" - group="0" - name="Cleft_Chin_Upper" - label="Upper Chin Cleft" - wearable="shape" - edit_group="shape_chin" - edit_group_order="7" - label_min="Round" - label_max="Cleft" + id="145" + group="1" + clothing_morph="true" + name="Bangs_Front_Down" + label="Front Bangs Down" + wearable="hair" + edit_group="hair_style" + label_min="Bangs" + label_max="Bangs Down" value_min="0" - value_max="1.5" - camera_elevation="0" - camera_distance=".28" - camera_angle="-20"> + value_max="5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="14" - group="0" - name="High_Cheek_Bones" - label="Cheek Bones" - wearable="shape" - edit_group="shape_head" - edit_group_order="10" - label_min="Low" - label_max="High" - value_min="-.5" + id="146" + group="1" + name="Bangs_Sides_Up" + label="Side Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Side Bangs" + label_max="Side Bangs Up" + value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="15" - group="0" - name="Ears_Out" - label="Ear Angle" - wearable="shape" - edit_group="shape_ears" - edit_group_order="2" - label_min="In" - label_max="Out" - value_min="-.5" - value_max="1.5" + id="147" + group="1" + clothing_morph="true" + name="Bangs_Sides_Down" + label="Side Bangs Down" + wearable="hair" + edit_group="hair_style" + label_min="Side Bangs" + label_max="Side Bangs Down" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> - <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="870" + id="148" group="1" - name="Pointy_Eyebrows" - label="Eyebrow Points" + name="Bangs_Back_Up" + label="Back Bangs Up" wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="4" - label_min="Smooth" - label_max="Pointy" - value_min="-.5" + edit_group="hair_style" + label_min="Back Bangs" + label_max="Back Bangs Up" + value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - <param - id="17" - group="0" - name="Square_Jaw" - label="Jaw Shape" - wearable="shape" - edit_group="shape_chin" - edit_group_order="2" - label_min="Pointy" - label_max="Square" - value_min="-.5" - value_max="1" - camera_distance=".3" - camera_elevation=".04" - camera_angle="-20"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="18" - group="0" - name="Puffy_Upper_Cheeks" - label="Upper Cheeks" - wearable="shape" - edit_group="shape_head" - edit_group_order="8" - label_min="Thin" - label_max="Puffy" - value_min="-1.5" - value_max="2.5" + id="149" + group="1" + name="Bangs_Back_Down" + label="Back Bangs Down" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + label_min="Back Bangs" + label_max="Back Bangs Down" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="19" - group="0" - name="Upturned_Nose_Tip" - label="Nose Tip Angle" - wearable="shape" - edit_group="shape_nose" - edit_group_order="7" - label_min="Downturned" - label_max="Upturned" - value_min="-1.5" + id="171" + group="1" + name="Hair_Front_Down" + label="Front Hair Down" + wearable="hair" + edit_group="hair_style" + label_min="Front Hair" + label_max="Front Hair Down" + value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".35" - camera_angle="15"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="20" - group="0" - name="Bulbous_Nose" - label="Nose Thickness" - wearable="shape" - edit_group="shape_nose" - edit_group_order="4" - label_min="Thin Nose" - label_max="Bulbous Nose" - show_simple="true" - value_min="-.5" - value_max="1.5" + id="172" + group="1" + name="Hair_Front_Up" + label="Front Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Front Hair" + label_max="Front Hair Up" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".3"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="21" - group="0" - name="Upper_Eyelid_Fold" - label="Upper Eyelid Fold" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="5" - label_min="Uncreased" - label_max="Creased" - value_min="-0.2" - value_max="1.3" + id="173" + group="1" + name="Hair_Sides_Down" + label="Sides Hair Down" + wearable="hair" + edit_group="hair_style" + label_min="Sides Hair" + label_max="Sides Hair Down" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="22" - group="0" - name="Attached_Earlobes" - label="Attached Earlobes" - wearable="shape" - edit_group="shape_ears" - edit_group_order="3" - label_min="Unattached" - label_max="Attached" + id="174" + group="1" + name="Hair_Sides_Up" + label="Sides Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Sides Hair" + label_max="Sides Hair Up" value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".3" - camera_angle="45"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="23" - group="0" - name="Baggy_Eyes" - label="Eye Bags" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="6" - label_min="Smooth" - label_max="Baggy" - value_min="-.5" - value_max="1.5" + id="175" + group="1" + name="Hair_Back_Down" + label="Back Hair Down" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + label_min="Back Hair" + label_max="Back Hair Down" + value_min="0" + value_max="3" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="765" - group="0" - name="Puffy_Lower_Lids" - label="Puffy Eyelids" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="6.1" - label_min="Flat" - label_max="Puffy" - value_min="-.3" - value_max="2.5" + id="176" + group="1" + name="Hair_Back_Up" + label="Back Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Back Hair" + label_max="Back Hair Up" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="24" + id="177" group="0" - name="Wide_Eyes" - label="Eye Opening" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="1.1" - label_min="Narrow" - label_max="Wide" - value_min="-1.5" - value_max="2" + name="Hair_Rumpled" + label="Rumpled Hair" show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + edit_group_order="14.5" + label_min="Smooth Hair" + label_max="Rumpled Hair" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="25" - group="0" - name="Wide_Lip_Cleft" - label="Lip Cleft" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="6" - label_min="Narrow" - label_max="Wide" - value_min="-.8" - value_max="1.5" - camera_elevation="0" - camera_distance=".28"> + id="178" + group="1" + name="Hair_Swept_Back" + label="Swept Back Hair" + wearable="hair" + edit_group="hair_style" + label_min="NotHair" + label_max="Swept Back" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="764" - group="0" - name="Lip_Cleft_Deep" - label="Lip Cleft Depth" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="5.8" - label_min="Shallow" - label_max="Deep" - value_min="-.5" - value_max="1.2" - camera_elevation="0" - camera_distance=".28"> + id="179" + group="1" + name="Hair_Swept_Forward" + label="Swept Forward Hair" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Swept Forward" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="26" + id="190" group="1" - wearable="shape" - name="Lips_Thin" - edit_group="driven" + name="Hair_Tilt_Right" + label="Hair Tilted Right" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Tilt Right" value_min="0" - value_max=".7"> + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="27" + id="191" + group="1" + name="Hair_Tilt_Left" + label="Hair Tilted Left" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Tilt Left" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> + + <param + id="192" group="0" - name="Wide_Nose_Bridge" - label="Bridge Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="6" - label_min="Narrow" - label_max="Wide" - value_min="-1.3" - value_max="1.2" + name="Bangs_Part_Middle" + label="Part Bangs" + wearable="hair" + edit_group="hair_style" + edit_group_order="20" + label_min="No Part" + label_max="Part Bangs" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="28" + id="640" group="1" - name="Lips_Fat" - wearable="shape" - edit_group="driven" + name="Hair_Egg_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-1.3" + value_max="1"> + <param_morph /> + </param> + + <param + id="641" + group="1" + name="Hair_Squash_Stretch_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-.5" + value_max="1"> + <param_morph /> + </param> + + <param + id="642" + group="1" + name="Hair_Square_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" value_min="0" - value_max="2"> + value_max="1"> <param_morph /> </param> <param - id="29" + id="643" group="1" - name="Wide_Upper_Lip" - wearable="shape" - edit_group="driven" - value_min="-.7" - value_max="1.3"> + name="Hair_Round_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="30" + id="644" group="1" - name="Wide_Lower_Lip" - wearable="shape" - edit_group="driven" - value_min="-.7" - value_max="1.3"> + name="Hair_Forehead_Round" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> <param_morph /> </param> - <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="872" + id="645" group="1" - name="Arced_Eyebrows" - label="Eyebrow Arc" + name="Hair_Forehead_Slant" wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="3" - label_min="Flat" - label_max="Arced" + edit_group="hair_style" + cross_wearable="true" value_min="0" value_max="1"> <param_morph /> </param> - <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> <param - id="871" + id="774" group="1" - name="Lower_Eyebrows" - label="Eyebrow Height" - show_simple="true" + name="Shear_Head_Hair" wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="2.5" - label_min="Higher" - label_max="Lower" + edit_group="hair_style" + cross_wearable="true" value_min="-2" value_max="2"> <param_morph /> </param> <param - id="35" - group="0" - name="Big_Ears" - label="Ear Size" - wearable="shape" - edit_group="shape_ears" - edit_group_order="1" - label_min="Small" - label_max="Large" + id="771" + group="1" + name="Elongate_Head_Hair" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" value_min="-1" - value_max="2" - camera_elevation=".1" - camera_distance=".3" - camera_angle="45"> + value_max="1"> <param_morph /> </param> <param - id="796" + id="674" group="0" - name="Pointy_Ears" - label="Ear Tips" - wearable="shape" - edit_group="shape_ears" - edit_group_order="4" - label_min="Flat" - label_max="Pointy" - value_min="-.4" - value_max="3" + name="Hair_Shear_Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="12" + label="Shear Back" + label_min="Full Back" + label_max="Sheared Back" + value_min="-1" + value_max="2" + value_default="-0.3" camera_elevation=".1" - camera_distance=".3" - camera_angle="45"> + camera_distance=".5" + camera_angle="100"> <param_morph /> </param> <param - id="185" + id="762" group="0" - name="Deep_Chin" - label="Chin Depth" - wearable="shape" - edit_group="shape_chin" - edit_group_order="3" - label_min="Shallow" - label_max="Deep" - value_min="-1" - value_max="1" + name="Hair_Shear_Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="11.8" + label="Shear Front" + show_simple="true" + label_min="Full Front" + label_max="Sheared Front" + value_min="0" + value_max="3" camera_elevation=".1" - camera_distance=".4" + camera_distance=".5" camera_angle="30"> <param_morph /> </param> <param - id="186" - group="1" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - label_min="Chin Heavy" - label_max="Forehead Heavy" - value_min="-1.3" - value_max="1" + id="754" + group="0" + name="Hair_Taper_Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="14" + label="Taper Back" + label_min="Wide Back" + label_max="Narrow Back" + value_min="-1" + value_max="2" + value_default="0" camera_elevation=".1" camera_distance=".5" - camera_angle="20"> + camera_angle="160"> <param_morph /> </param> <param - id="187" - group="1" - name="Squash_Stretch_Head" - label="Squash/Stretch Head" - wearable="shape" - edit_group="shape_head" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-.5" - value_max="1" + id="755" + group="0" + name="Hair_Taper_Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="13" + label="Taper Front" + label_min="Wide Front" + label_max="Narrow Front" + value_min="-1.5" + value_max="1.5" + value_default="0.05" camera_elevation=".1" camera_distance=".5" camera_angle="20"> - <param_morph> - <volume_morph - name="HEAD" - scale="-0.008 -0.006 0.015"/> - </param_morph> + <param_morph /> </param> <param - id="188" + id="782" group="1" - name="Square_Head" - wearable="shape" - label_min="Less Square" - label_max="More Square" + clothing_morph="true" + name="Hair_Pigtails_Short" + wearable="hair" + edit_group="hair_style" value_min="0" - value_max=".7" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> + value_max="1"> <param_morph /> </param> <param - id="189" + id="783" group="1" - wearable="shape" - name="Round_Head" - label_min="Less Round" - label_max="More Round" + clothing_morph="true" + name="Hair_Pigtails_Med" + wearable="hair" + edit_group="hair_style" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> + value_max="1"> <param_morph /> </param> <param - id="194" + id="790" group="1" - name="Eye_Spread" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-2" - value_max="2"> + clothing_morph="true" + name="Hair_Pigtails_Medlong" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="400" - sex="male" + id="784" group="1" - name="Displace_Hair_Facial" - label="Hair Thickess" + clothing_morph="true" + name="Hair_Pigtails_Long" wearable="hair" - edit_group="hair_facial" - label_min="Cropped Hair" - label_max="Bushy Hair" + edit_group="hair_style" value_min="0" - value_max="2"> + value_max="1"> <param_morph /> </param> <param - id="506" - group="0" - name="Mouth_Height" - wearable="shape" - label="Mouth Position" - show_simple="true" - edit_group="shape_mouth" - edit_group_order="4" - label_min="High" - label_max="Low" - value_min="-2" - value_max="2" - camera_distance=".3" - camera_elevation=".04"> + id="786" + group="1" + name="Hair_Ponytail_Short" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="633" + id="787" group="1" - name="Fat_Head" - label="Fat Head" - wearable="shape" - edit_group="shape_body" - label_min="Skinny" - label_max="Fat" + name="Hair_Ponytail_Med" + wearable="hair" + edit_group="hair_style" value_min="0" - value_max="1" - camera_elevation=".3"> - <param_morph/> + value_max="1"> + <param_morph /> </param> <param - id="630" + id="788" group="1" - name="Forehead_Round" - label="Round Forehead" - wearable="shape" - label_min="Less" - label_max="More" + name="Hair_Ponytail_Long" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" value_min="0" value_max="1"> <param_morph /> </param> + <!-- #end morph targets --> + </mesh> + + <mesh + type="hairMesh" + lod="1" + file_name="avatar_hair_1.llm" + min_pixel_width="160" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="2" + file_name="avatar_hair_2.llm" + min_pixel_width="80" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="3" + file_name="avatar_hair_3.llm" + min_pixel_width="40" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="4" + file_name="avatar_hair_4.llm" + min_pixel_width="20" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="5" + file_name="avatar_hair_5.llm" + min_pixel_width="0" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="headMesh" + lod="0" + file_name="avatar_head.llm" + min_pixel_width="320"> + <!-- + begin morph targets + ############# + tweakable morphs + ############# + --> <param - id="631" + id="20001" group="1" - name="Forehead_Slant" - label="Slanted Forehead" - wearable="shape" - label_min="Less" - label_max="More" - value_min="0" - value_max="1"> + name="Big_Brow" + value_min="-.3" + value_max="2"> <param_morph /> </param> <param - id="650" - group="0" - name="Eyelid_Corner_Up" - label="Outer Eye Corner" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".30"> + id="20002" + group="1" + name="Nose_Big_Out" + value_min="-0.8" + value_max="2.5"> <param_morph /> </param> <param - id="880" - group="0" - name="Eyelid_Inner_Corner_Up" - label="Inner Eye Corner" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4.2" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".30"> + id="20517" + group="1" + name="Wide_Nose" + value_min="-.5" + value_max="1"> <param_morph /> </param> - <param - id="653" - group="0" - name="Tall_Lips" - wearable="shape" - label="Lip Fullness" - show_simple="true" - edit_group="shape_mouth" - edit_group_order="2" - label_min="Less Full" - label_max="More Full" - value_min="-1" - value_max="2" - camera_distance=".3" - camera_elevation=".04"> + id="20020" + group="1" + name="Bulbous_Nose" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> - + <param - id="656" - group="0" + id="20656" + group="1" name="Crooked_Nose" - wearable="shape" - label="Crooked Nose" - edit_group="shape_nose" - edit_group_order="9" - label_min="Nose Left" - label_max="Nose Right" value_min="-2" - value_max="2" - camera_distance=".3" - camera_elevation=".04" - camera_angle="-20"> + value_max="2"> <param_morph /> </param> - + <param - id="657" + id="20004" group="1" - name="Smile_Mouth" - wearable="shape" - label="Mouth Corner" - edit_group="shape_mouth" - label_min="Corner Normal" - label_max="Corner Up" - value_min="0" - value_max="1.4" - camera_distance=".3" - camera_elevation=".04"> + name="Broad_Nostrils" + value_min="-.5" + value_max="1"> <param_morph /> </param> <param - id="658" + id="20653" group="1" - name="Frown_Mouth" - wearable="shape" - label="Mouth Corner" - edit_group="shape_mouth" - label_min="Corner Normal" - label_max="Corner Down" - value_min="0" - value_max="1.2" - camera_distance=".3" - camera_elevation=".04"> + name="Tall_Lips" + value_min="-1" + value_max="2"> <param_morph /> </param> - + <param - id="797" + id="20506" group="1" - name="Fat_Upper_Lip" - wearable="shape" - label="Fat Upper Lip" - edit_group="shape_mouth" - label_min="Normal Upper" - label_max="Fat Upper" - value_min="0" - value_max="1.5" - camera_distance=".3" - camera_elevation=".04"> + name="Mouth_Height" + value_min="-2" + value_max="2"> <param_morph /> </param> + + <param + id="20764" + group="1" + name="Lip_Cleft_Deep" + value_min="-.5" + value_max="1.2"> + <param_morph/> + </param> <param - id="798" + id="20025" group="1" - name="Fat_Lower_Lip" - wearable="shape" - label="Fat Lower Lip" - edit_group="shape_mouth" - label_min="Normal Lower" - label_max="Fat Lower" - value_min="0" - value_max="1.5" - camera_distance=".3" - camera_elevation=".04"> - <param_morph /> + name="Wide_Lip_Cleft" + value_min="-.8" + value_max="1.5"> + <param_morph/> </param> - + <param - id="660" + id="20663" group="1" - name="Shear_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Shear Left" - label_max="Shear Right" + name="Shift_Mouth" value_min="-2" value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> + value_default="0"> <param_morph /> </param> - + <param - id="770" + id="20035" group="1" - name="Elongate_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Flat Head" - label_max="Long Head" + name="Big_Ears" value_min="-1" - value_max="1" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> - <param_morph> - <volume_morph - name="HEAD" - scale="0.02 0.0 0.0"/> - </param_morph> + value_max="2"> + <param_morph/> </param> - + <param - id="663" - group="0" - name="Shift_Mouth" - wearable="shape" - label="Shift Mouth" - edit_group="shape_mouth" - edit_group_order="7" - label_min="Shift Left" - label_max="Shift Right" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".35" - camera_elevation=".04" - camera_angle="-20"> - <param_morph /> + id="20015" + group="1" + name="Ears_Out" + value_min="-.5" + value_max="1.5"> + <param_morph/> </param> - + <param - id="664" - group="0" - name="Pop_Eye" - wearable="shape" - label="Eye Pop" - edit_group="shape_eyes" - edit_group_order="8" - label_min="Pop Right Eye" - label_max="Pop Left Eye" - value_min="-1.3" - value_max="1.3" - value_default="0" - camera_elevation=".1" - camera_distance=".35"> + id="20796" + group="1" + name="Pointy_Ears" + value_min="-.4" + value_max="3"> <param_morph /> </param> - + <param - id="760" - group="0" - name="Jaw_Angle" - wearable="shape" - label="Jaw Angle" - edit_group="shape_chin" - edit_group_order="3.5" - label_min="Low Jaw" - label_max="High Jaw" - value_min="-1.2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="70"> + id="20185" + group="1" + name="Deep_Chin" + value_min="-1" + value_max="1"> <param_morph /> </param> - + <param - id="665" - group="0" + id="20665" + group="1" name="Jaw_Jut" - wearable="shape" - label="Jaw Jut" - edit_group="shape_chin" - edit_group_order="4" - label_min="Overbite" - label_max="Underbite" value_min="-2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="70"> + value_max="2"> <param_morph /> </param> - + <param - id="686" + id="20024" group="1" - name="Head_Eyes_Big" - wearable="shape" - label="Eye Size" - edit_group="shape_eyes" - label_min="Beady Eyes" - label_max="Anime Eyes" - show_simple="true" - value_min="-2" - value_max="2" - value_default="0"> + name="Wide_Eyes" + value_min="-1.5" + value_max="2"> <param_morph /> </param> - + <param - id="767" + id="20650" group="1" - name="Bug_Eyed_Head" - wearable="shape" - label="Eye Depth" - edit_group="shape_eyes" - edit_group_order="4.5" - label_min="Sunken Eyes" - label_max="Bug Eyes" - value_min="-2" - value_max="2" - value_default="0"> + name="Eyelid_Corner_Up" + value_min="-1.3" + value_max="1.2"> <param_morph /> </param> - - <!-- - #Fat_Lips = Fat_Lips 34 1 0 1 - #Wide_Lips = Wide_Lips 35 1 0 1 - #Wide_Nose = Wide_Nose 36 1 0 1 - --> - <!-- - ############## - # Facial Expression morphs - ############## - --> + <param - id="300" + id="20765" group="1" - name="Express_Closed_Mouth" - value_default="1" - value_min="0" - value_max="1"> + name="Puffy_Lower_Lids" + value_min="-.3" + value_max="2.5"> <param_morph /> </param> <param - id="301" + id="20759" group="1" - name="Express_Tongue_Out" - value_min="0" - value_max="1"> + name="Low_Septum_Nose" + value_min="-1" + value_max="1.5" + value_default="0.5"> <param_morph /> </param> <param - id="302" - group="1" - name="Express_Surprise_Emote" - value_min="0" - value_max="1"> + id="5" + group="0" + name="Cleft_Chin" + label="Chin Cleft" + wearable="shape" + edit_group="shape_chin" + edit_group_order="6" + label_min="Round" + label_max="Cleft" + value_min="-.1" + value_max="1" + camera_elevation="0" + camera_distance=".28" + camera_angle="-20"> <param_morph /> </param> <param - id="303" + id="20006" group="1" - name="Express_Wink_Emote" - value_min="0" - value_max="1"> - <param_morph /> - </param> - - <param - id="304" - group="1" - name="Express_Embarrassed_Emote" - value_min="0" + name="Bulbous_Nose_Tip" + value_min="-.3" value_max="1"> <param_morph /> </param> <param - id="305" + id="20007" group="1" - name="Express_Shrug_Emote" - value_min="0" - value_max="1"> + name="Weak_Chin" + value_min="-.5" + value_max=".5"> <param_morph /> </param> <param - id="306" + id="20008" group="1" - name="Express_Kiss" - value_min="0" - value_max="1"> + name="Double_Chin" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> <param - id="307" + id="20010" group="1" - name="Express_Bored_Emote" - value_min="0" - value_max="1"> + name="Sunken_Cheeks" + value_min="-1.5" + value_max="3"> <param_morph /> </param> <param - id="308" + id="20011" group="1" - name="Express_Repulsed_Emote" - value_min="0" - value_max="1"> + name="Noble_Nose_Bridge" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> <param - id="309" + id="20758" group="1" - name="Express_Disdain" - value_min="0" - value_max="1"> + name="Lower_Bridge_Nose" + value_min="-1.5" + value_max="1.5"> <param_morph /> </param> <param - id="310" - group="1" - name="Express_Afraid_Emote" - value_min="0" - value_max="1"> + id="12" + group="0" + name="Jowls" + wearable="shape" + edit_group="shape_chin" + edit_group_order="5" + label_min="Less" + label_max="More" + value_min="-.5" + value_max="2.5" + camera_elevation=".1" + camera_distance=".4" + camera_angle="0"> <param_morph /> </param> <param - id="311" - group="1" - name="Express_Worry_Emote" + id="13" + group="0" + name="Cleft_Chin_Upper" + label="Upper Chin Cleft" + wearable="shape" + edit_group="shape_chin" + edit_group_order="7" + label_min="Round" + label_max="Cleft" value_min="0" - value_max="1"> + value_max="1.5" + camera_elevation="0" + camera_distance=".28" + camera_angle="-20"> <param_morph /> </param> <param - id="312" + id="20014" group="1" - name="Express_Cry_Emote" - value_min="0" + name="High_Cheek_Bones" + value_min="-.5" value_max="1"> <param_morph /> </param> + <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="313" + id="870" group="1" - name="Express_Sad_Emote" - value_min="0" - value_max="1"> + name="Pointy_Eyebrows" + label="Eyebrow Points" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="4" + label_min="Smooth" + label_max="Pointy" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3"> <param_morph /> </param> <param - id="314" + id="20017" group="1" - name="Express_Anger_Emote" - value_min="0" + name="Square_Jaw" + value_min="-.5" value_max="1"> <param_morph /> </param> <param - id="315" + id="20018" group="1" - name="Express_Frown" - value_min="0" - value_max="1"> + name="Puffy_Upper_Cheeks" + value_min="-1.5" + value_max="2.5"> <param_morph /> </param> <param - id="316" + id="20019" group="1" - name="Express_Laugh_Emote" - value_min="0" + name="Upturned_Nose_Tip" + value_min="-1.5" value_max="1"> <param_morph /> </param> - + <param - id="317" + id="20021" group="1" - name="Express_Toothsmile" - value_min="0" - value_max="1"> + name="Upper_Eyelid_Fold" + value_min="-0.2" + value_max="1.3"> <param_morph /> </param> <param - id="318" - group="1" - name="Express_Smile" + id="22" + group="0" + name="Attached_Earlobes" + label="Attached Earlobes" + wearable="shape" + edit_group="shape_ears" + edit_group_order="3" + label_min="Unattached" + label_max="Attached" value_min="0" - value_max="1"> + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> <param_morph /> </param> <param - id="632" + id="20023" group="1" - name="Express_Open_Mouth" - value_min="0" - value_max="1"> + name="Baggy_Eyes" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> - <!-- - ############## - # Lipsync morphs - ############## - --> - <param - id="70" + id="26" group="1" - name="Lipsync_Aah" + wearable="shape" + name="Lips_Thin" + edit_group="driven" value_min="0" - value_max="1"> + value_max=".7"> <param_morph /> </param> <param - id="71" + id="20027" group="1" - name="Lipsync_Ooh" - value_min="0" - value_max="1"> + name="Wide_Nose_Bridge" + value_min="-1.3" + value_max="1.2"> <param_morph /> </param> - <!-- - ############## - # other morphs (not user controlled) - ############## - --> <param - id="40" + id="28" group="1" - name="Male_Head" + name="Lips_Fat" wearable="shape" edit_group="driven" value_min="0" - value_max="1"> + value_max="2"> <param_morph /> </param> <param - id="41" + id="29" group="1" - name="Old" - value_min="0" - value_max="1"> + name="Wide_Upper_Lip" + wearable="shape" + edit_group="driven" + value_min="-.7" + value_max="1.3"> <param_morph /> </param> - <!-- - ############## - # animatable morphs - ############## - --> <param - id="51" + id="30" group="1" - name="Furrowed_Eyebrows" - value_min="0" - value_max="1"> + name="Wide_Lower_Lip" + wearable="shape" + edit_group="driven" + value_min="-.7" + value_max="1.3"> <param_morph /> </param> + <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="53" + id="872" group="1" - name="Surprised_Eyebrows" + name="Arced_Eyebrows" + label="Eyebrow Arc" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="3" + label_min="Flat" + label_max="Arced" value_min="0" value_max="1"> <param_morph /> </param> + <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> <param - id="54" + id="871" group="1" - name="Worried_Eyebrows" - value_min="0" - value_max="1"> + name="Lower_Eyebrows" + label="Eyebrow Height" + show_simple="true" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="2.5" + label_min="Higher" + label_max="Lower" + value_min="-2" + value_max="2"> <param_morph /> </param> <param - id="55" + id="186" group="1" - name="Frown_Mouth" - value_min="0" - value_max="1"> + name="Egg_Head" + label="Egg Head" + wearable="shape" + edit_group="shape_head" + label_min="Chin Heavy" + label_max="Forehead Heavy" + value_min="-1.3" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="57" + id="187" group="1" - name="Smile_Mouth" - value_min="0" - value_max="1"> - <param_morph /> - </param> + name="Squash_Stretch_Head" + label="Squash/Stretch Head" + wearable="shape" + edit_group="shape_head" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph> + <volume_morph + name="HEAD" + scale="-0.008 -0.006 0.015"/> + </param_morph> + </param> <param - id="58" + id="188" group="1" - name="Blink_Left" + name="Square_Head" + wearable="shape" + label_min="Less Square" + label_max="More Square" value_min="0" - value_max="1"> + value_max=".7" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="59" + id="189" group="1" - name="Blink_Right" + wearable="shape" + name="Round_Head" + label_min="Less Round" + label_max="More Round" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + id="194" + group="1" + name="Eye_Spread" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="400" + sex="male" + group="1" + name="Displace_Hair_Facial" + label="Hair Thickess" + wearable="hair" + edit_group="hair_facial" + label_min="Cropped Hair" + label_max="Bushy Hair" + value_min="0" + value_max="2"> + <param_morph /> + </param> + + <param + id="633" + group="1" + name="Fat_Head" + label="Fat Head" + wearable="shape" + edit_group="shape_body" + label_min="Skinny" + label_max="Fat" + value_min="0" + value_max="1" + camera_elevation=".3"> + <param_morph/> + </param> + + <param + id="630" + group="1" + name="Forehead_Round" + label="Round Forehead" + wearable="shape" + label_min="Less" + label_max="More" value_min="0" value_max="1"> <param_morph /> </param> - <!-- - #end morph targets - --> - </mesh> + <param + id="631" + group="1" + name="Forehead_Slant" + label="Slanted Forehead" + wearable="shape" + label_min="Less" + label_max="More" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="1" - file_name="avatar_head_1.llm" - min_pixel_width="160" - reference="avatar_head.llm"> - </mesh> + <param + id="20880" + group="1" + name="Eyelid_Inner_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_morph /> + </param> + + <param + id="657" + group="1" + name="Smile_Mouth" + wearable="shape" + label="Mouth Corner" + edit_group="shape_mouth" + label_min="Corner Normal" + label_max="Corner Up" + value_min="0" + value_max="1.4" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="2" - file_name="avatar_head_2.llm" - min_pixel_width="80" - reference="avatar_head.llm"> - </mesh> + <param + id="658" + group="1" + name="Frown_Mouth" + wearable="shape" + label="Mouth Corner" + edit_group="shape_mouth" + label_min="Corner Normal" + label_max="Corner Down" + value_min="0" + value_max="1.2" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="3" - file_name="avatar_head_3.llm" - min_pixel_width="40" - reference="avatar_head.llm"> - </mesh> + <param + id="797" + group="1" + name="Fat_Upper_Lip" + wearable="shape" + label="Fat Upper Lip" + edit_group="shape_mouth" + label_min="Normal Upper" + label_max="Fat Upper" + value_min="0" + value_max="1.5" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="4" - file_name="avatar_head_4.llm" - min_pixel_width="0" - reference="avatar_head.llm"> - </mesh> + <param + id="798" + group="1" + name="Fat_Lower_Lip" + wearable="shape" + label="Fat Lower Lip" + edit_group="shape_mouth" + label_min="Normal Lower" + label_max="Fat Lower" + value_min="0" + value_max="1.5" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="eyelashMesh" - lod="0" - file_name="avatar_eyelashes.llm" - min_pixel_width="320"> <param - shared="1" id="660" group="1" name="Shear_Head" @@ -3374,7 +5958,6 @@ </param> <param - shared="1" id="770" group="1" name="Elongate_Head" @@ -3388,11 +5971,14 @@ value_default="0" camera_distance=".5" camera_elevation=".04"> - <param_morph /> + <param_morph> + <volume_morph + name="HEAD" + scale="0.02 0.0 0.0"/> + </param_morph> </param> <param - shared="1" id="664" group="0" name="Pop_Eye" @@ -3402,171 +5988,41 @@ edit_group_order="8" label_min="Pop Right Eye" label_max="Pop Left Eye" - value_min="-2" - value_max="2" + value_min="-1.3" + value_max="1.3" value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="-20"> + camera_elevation=".1" + camera_distance=".35"> <param_morph /> </param> <param - shared="1" - id="21" - group="0" - name="Upper_Eyelid_Fold" - label="Upper Eyelid Fold" - wearable="shape" - edit_group="shape_eyes" - label_min="Uncreased" - label_max="Creased" - value_min="-0.2" - value_max="1.3" - camera_elevation=".1" - camera_distance=".35"> + id="20760" + group="1" + name="Jaw_Angle" + value_min="-1.2" + value_max="2" + value_default="0"> <param_morph /> </param> <param - shared="1" - id="24" - group="0" - name="Wide_Eyes" - label="Eye Opening" + id="686" + group="1" + name="Head_Eyes_Big" wearable="shape" - edit_group="shape_eyes" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-1.5" - value_max="2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - <param - shared="1" - id="186" - group="1" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - label_min="Chin Heavy" - label_max="Forehead Heavy" - value_min="-1.3" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> - - <param - shared="1" - id="187" - group="1" - name="Squash_Stretch_Head" - label="Squash/Stretch Head" - wearable="shape" - edit_group="shape_head" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-.5" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> - - <param - shared="1" - id="194" - group="1" - name="Eye_Spread" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-2" - value_max="2"> - <param_morph /> - </param> - - <param - id="518" - group="0" - name="Eyelashes_Long" - wearable="shape" - label="Eyelash Length" - edit_group="shape_eyes" - edit_group_order="7" - label_min="Short" - label_max="Long" - value_min="-.3" - value_max="1.5" - camera_elevation=".1" - camera_distance=".30" - camera_angle="-20"> - <param_morph /> - </param> - - <param - shared="1" - id="650" - group="0" - name="Eyelid_Corner_Up" - label="Outer Eye Corner" - wearable="shape" - edit_group="shape_eyes" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - - <param - shared="1" - id="880" - group="0" - name="Eyelid_Inner_Corner_Up" - label="Inner Eye Corner" - wearable="shape" - edit_group="shape_eyes" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - <param - shared="1" - id="686" - group="1" - name="Head_Eyes_Big" - wearable="shape" - label="Eye Size" + label="Eye Size" edit_group="shape_eyes" label_min="Beady Eyes" label_max="Anime Eyes" + show_simple="true" value_min="-2" value_max="2" - show_simple="true" value_default="0"> <param_morph /> </param> <param - shared="1" id="767" group="1" name="Bug_Eyed_Head" @@ -3582,13 +6038,27 @@ <param_morph /> </param> + <!-- + #Fat_Lips = Fat_Lips 34 1 0 1 + #Wide_Lips = Wide_Lips 35 1 0 1 + #Wide_Nose = Wide_Nose 36 1 0 1 + --> <!-- ############## # Facial Expression morphs ############## --> <param - shared="1" + id="300" + group="1" + name="Express_Closed_Mouth" + value_default="1" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param id="301" group="1" name="Express_Tongue_Out" @@ -3598,7 +6068,6 @@ </param> <param - shared="1" id="302" group="1" name="Express_Surprise_Emote" @@ -3608,7 +6077,6 @@ </param> <param - shared="1" id="303" group="1" name="Express_Wink_Emote" @@ -3618,7 +6086,6 @@ </param> <param - shared="1" id="304" group="1" name="Express_Embarrassed_Emote" @@ -3628,7 +6095,6 @@ </param> <param - shared="1" id="305" group="1" name="Express_Shrug_Emote" @@ -3638,7 +6104,6 @@ </param> <param - shared="1" id="306" group="1" name="Express_Kiss" @@ -3648,7 +6113,6 @@ </param> <param - shared="1" id="307" group="1" name="Express_Bored_Emote" @@ -3658,7 +6122,6 @@ </param> <param - shared="1" id="308" group="1" name="Express_Repulsed_Emote" @@ -3668,7 +6131,6 @@ </param> <param - shared="1" id="309" group="1" name="Express_Disdain" @@ -3678,7 +6140,6 @@ </param> <param - shared="1" id="310" group="1" name="Express_Afraid_Emote" @@ -3688,7 +6149,15 @@ </param> <param - shared="1" + id="311" + group="1" + name="Express_Worry_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param id="312" group="1" name="Express_Cry_Emote" @@ -3698,7 +6167,6 @@ </param> <param - shared="1" id="313" group="1" name="Express_Sad_Emote" @@ -3708,7 +6176,6 @@ </param> <param - shared="1" id="314" group="1" name="Express_Anger_Emote" @@ -3718,7 +6185,6 @@ </param> <param - shared="1" id="315" group="1" name="Express_Frown" @@ -3728,7 +6194,6 @@ </param> <param - shared="1" id="316" group="1" name="Express_Laugh_Emote" @@ -3738,7 +6203,6 @@ </param> <param - shared="1" id="317" group="1" name="Express_Toothsmile" @@ -3748,7 +6212,6 @@ </param> <param - shared="1" id="318" group="1" name="Express_Smile" @@ -3757,16 +6220,10 @@ <param_morph /> </param> - <!-- - ############## - # other morphs (not user controlled) - ############## - --> <param - shared="1" - id="41" + id="632" group="1" - name="Old" + name="Express_Open_Mouth" value_min="0" value_max="1"> <param_morph /> @@ -3774,835 +6231,584 @@ <!-- ############## - # animatable morphs + # Lipsync morphs ############## - --> + --> + <param - shared="1" - id="58" + id="70" group="1" - name="Blink_Left" + name="Lipsync_Aah" value_min="0" value_max="1"> <param_morph /> </param> <param - shared="1" - id="59" + id="71" group="1" - name="Blink_Right" + name="Lipsync_Ooh" value_min="0" value_max="1"> <param_morph /> </param> - </mesh> - <!-- - #headMesh2 = - #headMesh3 = - --> - <mesh - type="upperBodyMesh" - lod="0" - file_name="avatar_upper_body.llm" - min_pixel_width="320"> <!-- - #begin morph targets - ############# - # tweakable morphs - ############# + ############## + # other morphs (not user controlled) + ############## --> <param - id="104" + id="40" group="1" - name="Big_Belly_Torso" + name="Male_Head" wearable="shape" edit_group="driven" value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.075 0.04 0.03" - pos="0.07 0 -0.07"/> - <volume_morph - name="PELVIS" - scale="0.075 0.04 0.03" - pos="0.07 0 -0.02"/> - </param_morph> + <param_morph /> </param> <param - id="626" - sex="female" + id="41" group="1" - name="Big_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Small" - label_max="Large" + name="Old" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance="1" - camera_angle="15"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0273 0.0273 0.0273" - pos="0.038 0.024 -0.016"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0273 0.0273 0.0273" - pos="0.038 -0.024 -0.016"/> - </param_morph> + value_max="1"> + <param_morph /> </param> + <!-- + ############## + # animatable morphs + ############## + --> <param - id="627" - sex="female" + id="51" group="1" - name="Small_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Large" - label_max="Small" + name="Furrowed_Eyebrows" value_min="0" - value_max="1" - camera_elevation="0" - camera_distance=".28"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="-0.05 0.0 0.0" - pos="-0.01 -0.01 -0.02"/> - <volume_morph - name="RIGHT_PEC" - scale="-0.05 0.0 0.0" - pos="-0.01 -0.01 -0.02"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="843" - sex="female" + id="53" group="1" - name="No_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Some" - label_max="None" + name="Surprised_Eyebrows" value_min="0" - value_max="1" - camera_elevation="0" - camera_distance=".28"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="-0.051 0.0 0.0" - pos="-0.02 -0.01 -0.03"/> - <volume_morph - name="RIGHT_PEC" - scale="-0.051 0.0 0.0" - pos="-0.02 -0.01 -0.03"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="106" + id="54" group="1" - name="Muscular_Torso" - label="Torso Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Muscular" + name="Worried_Eyebrows" value_min="0" - value_max="1.4" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="L_CLAVICLE" - scale="0.02 0.0 0.005" - pos="0.0 0 0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.015 0.0 0.005" - pos="0.015 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.02 0.0 0.005" - pos="0.0 0 0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.015 0.0 0.005" - pos="0.015 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.005 0 0"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="648" + id="55" group="1" - sex="female" - name="Scrawny_Torso" - label="Torso Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Scrawny" + name="Frown_Mouth" value_min="0" - value_max="1.3" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="UPPER_BACK" - scale="-0.01 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="CHEST" - scale="-0.01 -0.01 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="677" + id="57" group="1" - sex="male" - name="Scrawny_Torso_Male" - label="Torso Scrawny" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Scrawny" + name="Smile_Mouth" value_min="0" - value_max="1.3" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="BELLY" - scale="-0.01 -0.01 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="UPPER_BACK" - scale="-0.01 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="CHEST" - scale="-0.02 -0.02 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="634" + id="58" group="1" - name="Fat_Torso" - label="Fat Torso" - wearable="shape" - edit_group="shape_body" - label_min="skinny" - label_max="fat" + name="Blink_Left" value_min="0" - value_max="1" - camera_elevation=".3"> - <param_morph> - <volume_morph - name="CHEST" - scale="0.02 0.03 0.03" - pos="0 0 -0.03"/> - <volume_morph - name="PELVIS" - scale="0.02 0.03 0.03" - pos="0 0 -0.03"/> - <volume_morph - name="UPPER_BACK" - scale="0.01 0.03 0.0" - pos="-0.03 0 0"/> - <volume_morph - name="LOWER_BACK" - scale="0.04 0.06 0.0" - pos="-0.06 0 0"/> - <volume_morph - name="LEFT_HANDLE" - pos="0.0 0.08 0.0"/> - <volume_morph - name="RIGHT_HANDLE" - pos="0.0 -0.08 0.0"/> - <volume_morph - name="LEFT_PEC" - scale="0.0367 0.0367 0.016" - pos="0.00 -0.005 -0.013"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0367 0.0367 0.016" - pos="0.00 0.005 -0.013"/> - <volume_morph - name="BELLY" - scale="0.09 0.08 0.07" - pos="0 0 -0.05"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 0.0 0.015"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.02 0.0 0.02" - pos="0.0 0.0 -0.02"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 0.0 0.015"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.02 0.0 0.02" - pos="0.0 0.0 -0.02"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="NECK" - scale="0.015 0.01 0.0"/> - <volume_morph - name="HEAD" - scale="0.0 0.0 0.01" - pos="0 0 -0.01"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="507" - group="0" - sex="female" - name="Breast_Gravity" - label="Breast Buoyancy" - wearable="shape" - edit_group="shape_torso" - edit_group_order="7" - label_min="Less Gravity" - label_max="More Gravity" - value_default="0" - value_min="-1.5" - value_max="2" - camera_elevation=".3" - camera_distance=".8"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.004 0.0 -0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.004 0.0 -0.01"/> - </param_morph> - </param> - - <param - id="628" + id="59" group="1" - name="Displace_Loose_Upperbody" - label="Shirt Fit" - wearable="shirt" - edit_group="driven" - clothing_morph="true" + name="Blink_Right" value_min="0" - value_max="1" - value_default="0"> + value_max="1"> <param_morph /> </param> + <!-- + #end morph targets + --> + </mesh> + + <mesh + type="headMesh" + lod="1" + file_name="avatar_head_1.llm" + min_pixel_width="160" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="2" + file_name="avatar_head_2.llm" + min_pixel_width="80" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="3" + file_name="avatar_head_3.llm" + min_pixel_width="40" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="4" + file_name="avatar_head_4.llm" + min_pixel_width="0" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="eyelashMesh" + lod="0" + file_name="avatar_eyelashes.llm" + min_pixel_width="320"> <param - id="840" - group="0" - name="Shirtsleeve_flair" - label="Sleeve Looseness" - show_simple="true" - wearable="shirt" - edit_group="shirt" - edit_group_order="6" - clothing_morph="true" - label_min="Tight Sleeves" - label_max="Loose Sleeves" - value_min="0" - value_max="1.5" - camera_distance="1.8" - camera_angle="30" - camera_elevation="-.3"> + shared="1" + id="660" + group="1" + name="Shear_Head" + wearable="shape" + label="Shear Face" + edit_group="shape_head" + label_min="Shear Left" + label_max="Shear Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> <param_morph /> </param> <param - id="855" + shared="1" + id="770" group="1" - name="Love_Handles" + name="Elongate_Head" wearable="shape" - edit_group="driven" - value_default="0" + label="Shear Face" + edit_group="shape_head" + label_min="Flat Head" + label_max="Long Head" value_min="-1" - value_max="2"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 0.02 0.0"/> - <volume_morph - name="LOWER_BACK" - scale="0.0 0.02 0.0"/> - <volume_morph - name="LEFT_HANDLE" - pos="0.0 0.025 0.0"/> - <volume_morph - name="RIGHT_HANDLE" - pos="0.0 -0.025 0.0"/> - </param_morph> + value_max="1" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> + <param_morph /> </param> <param - id="684" + shared="1" + id="664" group="0" - sex="female" - name="Breast_Female_Cleavage" - label="Breast Cleavage" + name="Pop_Eye" wearable="shape" - edit_group="shape_torso" + label="Eye Pop" + edit_group="shape_eyes" edit_group_order="8" - label_min="Separate" - label_max="Join" + label_min="Pop Right Eye" + label_max="Pop Left Eye" + value_min="-2" + value_max="2" value_default="0" - value_min="-.3" - value_max="1.3" - camera_elevation=".3" - camera_distance=".8"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 -0.026 0.0"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.026 0.0"/> - </param_morph> + camera_distance=".5" + camera_elevation=".04" + camera_angle="-20"> + <param_morph /> </param> - + <param - id="685" - group="0" - sex="male" - name="Chest_Male_No_Pecs" - label="Pectorals" + shared="1" + id="186" + group="1" + name="Egg_Head" + label="Egg Head" wearable="shape" - edit_group="shape_torso" - edit_group_order="5" - label_min="Big Pectorals" - label_max="Sunken Chest" - value_default="0" - value_min="-0.5" - value_max="1.1" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="-0.03 -0.024 -0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="-0.03 0.024 -0.01"/> - </param_morph> + edit_group="shape_head" + label_min="Chin Heavy" + label_max="Forehead Heavy" + value_min="-1.3" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> </param> - <!-- ############# # - other morphs (not user controlled) - ############# --> <param - id="100" + shared="1" + id="187" group="1" - name="Male_Torso" - wearable="shape" - edit_group="driven" - label_min="Male_Torso" - value_min="0" - value_max="1"> - <param_morph> - <volume_morph - name="CHEST" - scale="0.03 0.04 0.02" - pos="-0.03 0 -0.01"/> - <volume_morph - name="BELLY" - scale="0.03 0.03 0.0" - pos="-0.03 0 0.02"/> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.008 -0.03 0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.008 0.03 0.01"/> - <volume_morph - name="L_CLAVICLE" - scale="0.02 0.0 0.01" - pos="-0.02 0 0"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.0 0.0 -0.005"/> - <volume_morph - name="R_CLAVICLE" - scale="0.02 0.0 0.01" - pos="-0.02 0 0"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.0 0.0 -0.005"/> - <volume_morph - name="NECK" - scale="0.015 0.01 0.0"/> - <volume_morph - name="HEAD" - scale="0.0 0.0 0.01" - pos="0 0 -0.01"/> - </param_morph> + name="Squash_Stretch_Head" + label="Squash/Stretch Head" + wearable="shape" + edit_group="shape_head" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + shared="1" + id="194" + group="1" + name="Eye_Spread" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="518" + group="0" + name="Eyelashes_Long" + wearable="shape" + label="Eyelash Length" + edit_group="shape_eyes" + edit_group_order="7" + label_min="Short" + label_max="Long" + value_min="-.3" + value_max="1.5" + camera_elevation=".1" + camera_distance=".30" + camera_angle="-20"> + <param_morph /> + </param> + + <param + shared="1" + id="686" + group="1" + name="Head_Eyes_Big" + wearable="shape" + label="Eye Size" + edit_group="shape_eyes" + label_min="Beady Eyes" + label_max="Anime Eyes" + value_min="-2" + value_max="2" + show_simple="true" + value_default="0"> + <param_morph /> + </param> + + <param + shared="1" + id="767" + group="1" + name="Bug_Eyed_Head" + wearable="shape" + label="Eye Depth" + edit_group="shape_eyes" + edit_group_order="4.5" + label_min="Sunken Eyes" + label_max="Bug Eyes" + value_min="-2" + value_max="2" + value_default="0"> + <param_morph /> + </param> + + <param + shared="1" + id="20021" + group="1" + name="Upper_Eyelid_Fold" + value_min="-0.2" + value_max="1.3"> + <param_morph /> + </param> + + <param + shared="1" + id="20024" + group="1" + name="Wide_Eyes" + value_min="-1.5" + value_max="2"> + <param_morph /> + </param> + + <param + shared="1" + id="20650" + group="1" + name="Eyelid_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_morph /> </param> + <param + shared="1" + id="20880" + group="1" + name="Eyelid_Inner_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_morph /> + </param> + <!-- ############## - # animatable morphs + # Facial Expression morphs ############## --> <param - id="101" + shared="1" + id="301" group="1" - name="Hands_Relaxed" + name="Express_Tongue_Out" value_min="0" value_max="1"> <param_morph /> </param> <param - id="102" + shared="1" + id="302" group="1" - name="Hands_Point" + name="Express_Surprise_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="103" + shared="1" + id="303" group="1" - name="Hands_Fist" + name="Express_Wink_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="666" + shared="1" + id="304" group="1" - name="Hands_Relaxed_L" + name="Express_Embarrassed_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="667" + shared="1" + id="305" group="1" - name="Hands_Point_L" + name="Express_Shrug_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="668" + shared="1" + id="306" group="1" - name="Hands_Fist_L" + name="Express_Kiss" value_min="0" value_max="1"> <param_morph /> </param> <param - id="669" + shared="1" + id="307" group="1" - name="Hands_Relaxed_R" + name="Express_Bored_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="670" + shared="1" + id="308" group="1" - name="Hands_Point_R" + name="Express_Repulsed_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="671" + shared="1" + id="309" group="1" - name="Hands_Fist_R" + name="Express_Disdain" value_min="0" value_max="1"> <param_morph /> </param> <param - id="672" + shared="1" + id="310" group="1" - name="Hands_Typing" + name="Express_Afraid_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="766" + shared="1" + id="312" group="1" - name="Hands_Salute_R" + name="Express_Cry_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="791" + shared="1" + id="313" group="1" - name="Hands_Peace_R" + name="Express_Sad_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="792" + shared="1" + id="314" group="1" - name="Hands_Spread_R" + name="Express_Anger_Emote" value_min="0" value_max="1"> <param_morph /> </param> - <!-- - ############# - # physics morphs (not user controlled) - ############# - --> <param - id="1200" + shared="1" + id="315" group="1" - sex="female" - name="Breast_Physics_UpDown_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-3" - value_max="3"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.0 -0.01"/> - </param_morph> + name="Express_Frown" + value_min="0" + value_max="1"> + <param_morph /> </param> <param - id="1201" + shared="1" + id="316" group="1" - sex="female" - name="Breast_Physics_InOut_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-1.25" - value_max="1.25"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 -0.026 0.0"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.026 -0.0"/> - </param_morph> + name="Express_Laugh_Emote" + value_min="0" + value_max="1"> + <param_morph /> </param> <param - id="1204" + shared="1" + id="317" group="1" - name="Belly_Physics_Torso_UpDown_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-1" + name="Express_Toothsmile" + value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 0.0 0.0" - pos="0.0 0.0 0.05"/> - </param_morph> + <param_morph /> </param> <param - id="1207" + shared="1" + id="318" group="1" - name="Breast_Physics_LeftRight_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-2" - value_max="2"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.03 0.0"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.03 0.0"/> - </param_morph> + name="Express_Smile" + value_min="0" + value_max="1"> + <param_morph /> </param> <!-- - #end morph targets - --> - - </mesh> - - <mesh - type="upperBodyMesh" - lod="1" - file_name="avatar_upper_body_1.llm" - min_pixel_width="160" - reference="avatar_upper_body.llm"> - </mesh> - - <mesh - type="upperBodyMesh" - lod="2" - file_name="avatar_upper_body_2.llm" - min_pixel_width="80" - reference="avatar_upper_body.llm"> - </mesh> + ############## + # other morphs (not user controlled) + ############## + --> + <param + shared="1" + id="41" + group="1" + name="Old" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <mesh - type="upperBodyMesh" - lod="3" - file_name="avatar_upper_body_3.llm" - min_pixel_width="40" - reference="avatar_upper_body.llm"> - </mesh> + <!-- + ############## + # animatable morphs + ############## + --> + <param + shared="1" + id="58" + group="1" + name="Blink_Left" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <mesh - type="upperBodyMesh" - lod="4" - file_name="avatar_upper_body_4.llm" - min_pixel_width="0" - reference="avatar_upper_body.llm"> + <param + shared="1" + id="59" + group="1" + name="Blink_Right" + value_min="0" + value_max="1"> + <param_morph /> + </param> </mesh> <!-- - #upperBodyMesh2 = - #upperBodyMesh3 = + #headMesh2 = + #headMesh3 = --> <mesh - type="lowerBodyMesh" + type="upperBodyMesh" lod="0" - file_name="avatar_lower_body.llm" + file_name="avatar_upper_body.llm" min_pixel_width="320"> <!-- #begin morph targets @@ -4611,315 +6817,412 @@ ############# --> <param - id="156" + id="104" group="1" - name="Big_Belly_Legs" + name="Big_Belly_Torso" wearable="shape" edit_group="driven" value_min="0" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="BELLY" + scale="0.075 0.04 0.03" + pos="0.07 0 -0.07"/> + <volume_morph + name="PELVIS" + scale="0.075 0.04 0.03" + pos="0.07 0 -0.02"/> + </param_morph> </param> - <param - id="151" + id="626" + sex="female" group="1" - name="Big_Butt_Legs" - label="Butt Size" + name="Big_Chest" + label="Chest Size" wearable="shape" - edit_group="shape_legs" - label_min="Regular" + edit_group="shape_torso" + label_min="Small" label_max="Large" value_min="0" - value_max="1"> + value_max="1" + camera_elevation=".1" + camera_distance="1" + camera_angle="15"> <param_morph> <volume_morph - name="PELVIS" - scale="0.03 0.0 0.02" - pos="-0.03 0 -0.025"/> - </param_morph> + name="LEFT_PEC" + scale="0.0273 0.0273 0.0273" + pos="0.038 0.024 -0.016"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0273 0.0273 0.0273" + pos="0.038 -0.024 -0.016"/> + </param_morph> </param> <param - id="794" + id="627" + sex="female" group="1" - name="Small_Butt" - label="Butt Size" + name="Small_Chest" + label="Chest Size" wearable="shape" - edit_group="shape_legs" - label_min="Regular" + edit_group="shape_torso" + label_min="Large" label_max="Small" value_min="0" - value_max="1"> + value_max="1" + camera_elevation="0" + camera_distance=".28"> <param_morph> <volume_morph - name="PELVIS" - scale="-0.01 0.0 0.0" - pos="0.01 0 0.0"/> + name="LEFT_PEC" + scale="-0.05 0.0 0.0" + pos="-0.01 -0.01 -0.02"/> <volume_morph - name="BUTT" - scale="0.0 0.0886 0.0" - pos="0.03 0 0.0"/> - </param_morph> + name="RIGHT_PEC" + scale="-0.05 0.0 0.0" + pos="-0.01 0.01 -0.02"/> + </param_morph> </param> <param - id="152" + id="843" + sex="female" group="1" - name="Muscular_Legs" - label="Leg Muscles" - show_simple="true" + name="No_Chest" + label="Chest Size" wearable="shape" - edit_group="shape_legs" - label_min="Regular Muscles" - label_max="More Muscles" + edit_group="shape_torso" + label_min="Some" + label_max="None" value_min="0" - value_max="1.5" - camera_distance="1.3" - camera_elevation="-.5"> + value_max="1" + camera_elevation="0" + camera_distance=".28"> <param_morph> <volume_morph - name="L_UPPER_LEG" - scale="0.015 0.015 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="L_LOWER_LEG" - scale="0.01 0.01 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="0.015 0.015 0.0" - pos="0.0 0 0.0"/> + name="LEFT_PEC" + scale="-0.051 0.0 0.0" + pos="-0.02 -0.01 -0.03"/> <volume_morph - name="R_LOWER_LEG" - scale="0.01 0.01 0.0" - pos="0.0 0 0.0"/> - </param_morph> + name="RIGHT_PEC" + scale="-0.051 0.0 0.0" + pos="-0.02 0.01 -0.03"/> + </param_morph> </param> <param - id="651" + id="106" group="1" - name="Scrawny_Legs" - label="Scrawny Leg" + name="Muscular_Torso" + label="Torso Muscles" + sex="male" + show_simple="true" wearable="shape" - edit_group="shape_legs" - label_min="Regular Muscles" - label_max="Less Muscles" + edit_group="shape_torso" + label_min="Regular" + label_max="Muscular" value_min="0" - value_max="1.5" - camera_distance="1.3" - camera_elevation="-.5"> + value_max="1.4" + camera_elevation=".3" + camera_distance="1.2"> <param_morph> <volume_morph - name="L_UPPER_LEG" - scale="-0.03 -0.03 0.0" - pos="0.0 0 0.0"/> + name="L_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> <volume_morph - name="L_LOWER_LEG" - scale="-0.015 -0.015 0.0" - pos="0.0 0 0.0"/> + name="L_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> <volume_morph - name="R_UPPER_LEG" - scale="-0.03 -0.03 0.0" - pos="0.0 0 0.0"/> + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> <volume_morph - name="R_LOWER_LEG" - scale="-0.015 -0.015 0.0" - pos="0.0 0 0.0"/> + name="R_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> </param_morph> </param> <param - id="853" - group="1" - name="Bowed_Legs" - label="Knee Angle" + id="107" + group="1" + name="Muscular_Torso" + label="Torso Muscles" + sex="female" + show_simple="true" wearable="shape" - value_min="-1" - value_max="1"> + edit_group="shape_torso" + label_min="Regular" + label_max="Muscular" + value_min="0" + value_max="1.4" + camera_elevation=".3" + camera_distance="1.2"> <param_morph> <volume_morph - name="L_UPPER_LEG" - pos="0.0 0.03 0.0"/> + name="L_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> <volume_morph - name="L_LOWER_LEG" - pos="0.0 0.03 0.0"/> + name="L_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> <volume_morph - name="R_UPPER_LEG" - pos="0.0 -0.03 0.0"/> + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> <volume_morph - name="R_LOWER_LEG" - pos="0.0 -0.03 0.0"/> + name="R_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> </param_morph> </param> <param - id="500" - group="1" - name="Shoe_Heel_Height" - label="Heel Height" - wearable="shoes" - edit_group="shoes" - label_min="Low Heels" - label_max="High Heels" - value_min="0" - value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="501" + id="648" group="1" - name="Shoe_Platform_Height" - label="Platform Height" - wearable="shoes" - edit_group="shoes" - label_min="Low Platforms" - label_max="High Platforms" + sex="female" + name="Scrawny_Torso" + label="Torso Muscles" + show_simple="true" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Scrawny" value_min="0" - value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="508" - group="0" - name="Shoe_Platform_Width" - label="Platform Width" - wearable="shoes" - edit_group="shoes" - edit_group_order="7" - label_min="Narrow" - label_max="Wide" - value_min="-1" - value_max="2" - camera_angle="15" - camera_distance="1.5" - camera_elevation="-1"> - <param_morph /> + value_max="1.3" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="UPPER_BACK" + scale="-0.01 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="CHEST" + scale="-0.01 -0.01 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + </param_morph> </param> <param - id="509" + id="677" group="1" - name="Shoe_Heel_Point" - label="Heel Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Heels" - label_max="Pointy Heels" + sex="male" + name="Scrawny_Torso_Male" + label="Torso Scrawny" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Scrawny" value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> + value_max="1.3" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="BELLY" + scale="-0.01 -0.01 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="UPPER_BACK" + scale="-0.01 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="CHEST" + scale="-0.02 -0.02 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + </param_morph> </param> <param - id="510" + id="634" group="1" - name="Shoe_Heel_Thick" - label="Heel Shape" - wearable="shoes" - edit_group="shoes" - label_min="default Heels" - label_max="Thick Heels" + name="Fat_Torso" + label="Fat Torso" + wearable="shape" + edit_group="shape_body" + label_min="skinny" + label_max="fat" value_min="0" value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="511" - group="1" - name="Shoe_Toe_Point" - label="Toe Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Toe" - label_max="Pointy Toe" - value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="512" - group="1" - name="Shoe_Toe_Square" - label="Toe Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Toe" - label_max="Square Toe" - value_min="0" - value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="654" - group="0" - name="Shoe_Toe_Thick" - label="Toe Thickness" - wearable="shoes" - edit_group="shoes" - edit_group_order="5" - label_min="Flat Toe" - label_max="Thick Toe" - value_min="0" - value_max="2" - camera_angle="15" - camera_distance="1.5" - camera_elevation="-1"> - <param_morph /> + camera_elevation=".3"> + <param_morph> + <volume_morph + name="CHEST" + scale="0.02 0.03 0.03" + pos="0 0 -0.03"/> + <volume_morph + name="PELVIS" + scale="0.02 0.03 0.03" + pos="0 0 -0.03"/> + <volume_morph + name="UPPER_BACK" + scale="0.01 0.03 0.0" + pos="-0.03 0 0"/> + <volume_morph + name="LOWER_BACK" + scale="0.04 0.06 0.0" + pos="-0.06 0 0"/> + <volume_morph + name="LEFT_HANDLE" + pos="0.0 0.08 0.0"/> + <volume_morph + name="RIGHT_HANDLE" + pos="0.0 -0.08 0.0"/> + <volume_morph + name="LEFT_PEC" + scale="0.0367 0.0367 0.016" + pos="0.00 -0.005 -0.013"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0367 0.0367 0.016" + pos="0.00 0.005 -0.013"/> + <volume_morph + name="BELLY" + scale="0.09 0.08 0.07" + pos="0 0 -0.05"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 0.0 0.015"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.02 0.0 0.02" + pos="0.0 0.0 -0.02"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 0.0 0.015"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.02 0.0 0.02" + pos="0.0 0.0 -0.02"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="NECK" + scale="0.015 0.01 0.0"/> + <volume_morph + name="HEAD" + scale="0.0 0.0 0.01" + pos="0 0 -0.01"/> + </param_morph> </param> <param - id="515" + id="507" group="0" - name="Foot_Size" - label="Foot Size" + sex="female" + name="Breast_Gravity" + label="Breast Buoyancy" wearable="shape" - edit_group="shape_legs" - edit_group_order="6" - label_min="Small" - label_max="Big" - value_min="-1" - value_max="3" - camera_angle="45" - camera_distance="1.1" - camera_elevation="-1"> + edit_group="shape_torso" + edit_group_order="7" + label_min="Less Gravity" + label_max="More Gravity" + value_default="0" + value_min="-1.5" + value_max="2" + camera_elevation=".3" + camera_distance=".8"> <param_morph> <volume_morph - name="L_FOOT" - scale="0.02 0.01 0.0" - pos="0.01 0 0"/> + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.004 0.0 -0.01"/> <volume_morph - name="R_FOOT" - scale="0.02 0.01 0.0" - pos="0.01 0 0"/> + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.004 0.0 -0.01"/> </param_morph> </param> - + <param - id="516" + id="628" group="1" - name="Displace_Loose_Lowerbody" - label="Pants Fit" - wearable="pants" + name="Displace_Loose_Upperbody" + label="Shirt Fit" + wearable="shirt" edit_group="driven" clothing_morph="true" value_min="0" @@ -4929,17 +7232,17 @@ </param> <param - id="625" + id="840" group="0" - name="Leg_Pantflair" - label="Cuff Flare" + name="Shirtsleeve_flair" + label="Sleeve Looseness" show_simple="true" - wearable="pants" - edit_group="pants" - edit_group_order="3" + wearable="shirt" + edit_group="shirt" + edit_group_order="6" clothing_morph="true" - label_min="Tight Cuffs" - label_max="Flared Cuffs" + label_min="Tight Sleeves" + label_max="Loose Sleeves" value_min="0" value_max="1.5" camera_distance="1.8" @@ -4949,2856 +7252,2906 @@ </param> <param - id="793" - group="1" - name="Leg_Longcuffs" - label="Longcuffs" - wearable="pants" - edit_group="driven" - clothing_morph="true" - value_min="0" - value_max="3" - value_default="0"> - <param_morph /> - </param> - - <param - id="638" - group="0" - name="Low_Crotch" - label="Pants Crotch" - wearable="pants" - clothing_morph="true" - edit_group="pants" - edit_group_order="4" - label_min="High and Tight" - label_max="Low and Loose" - value_min="0" - value_max="1.3" - camera_distance="1.2" - camera_angle="-20" - camera_elevation="-.3"> - <param_morph /> - </param> - - <param - id="635" + id="855" group="1" - name="Fat_Legs" - label="Fat Torso" + name="Love_Handles" wearable="shape" - edit_group="shape_body" - label_min="skinny" - label_max="fat" - value_min="0" - value_max="1"> + edit_group="driven" + value_default="0" + value_min="-1" + value_max="2"> <param_morph> <volume_morph - name="PELVIS" - scale="0.03 0.06 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="0.02 0.02 0.0" - pos="0.0 -0.02 0.0"/> + name="BELLY" + scale="0.0 0.02 0.0"/> <volume_morph - name="R_LOWER_LEG" - scale="0.01 0.01 0.0"/> + name="LOWER_BACK" + scale="0.0 0.02 0.0"/> <volume_morph - name="L_UPPER_LEG" - scale="0.02 0.02 0.0" - pos="0.0 0.02 0.0"/> + name="LEFT_HANDLE" + pos="0.0 0.025 0.0"/> <volume_morph - name="L_LOWER_LEG" - scale="0.01 0.01 0.0"/> + name="RIGHT_HANDLE" + pos="0.0 -0.025 0.0"/> </param_morph> </param> <param - id="854" - group="1" - name="Saddlebags" + id="684" + group="0" + sex="female" + name="Breast_Female_Cleavage" + label="Breast Cleavage" wearable="shape" - edit_group="driven" - value_min="-.5" - value_max="3"> - <param_morph> - <volume_morph - name="PELVIS" - scale="0.0 0.025 0.0"/> - </param_morph> - + edit_group="shape_torso" + edit_group_order="8" + label_min="Separate" + label_max="Join" + value_default="0" + value_min="-.3" + value_max="1.3" + camera_elevation=".3" + camera_distance=".8"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 -0.026 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.026 0.0"/> + </param_morph> </param> - + <param - id="879" + id="685" group="0" sex="male" - name="Male_Package" - label="Package" + name="Chest_Male_No_Pecs" + label="Pectorals" wearable="shape" - edit_group="shape_legs" - edit_group_order="4.6" - label_min="Coin Purse" - label_max="Duffle Bag" + edit_group="shape_torso" + edit_group_order="5" + label_min="Big Pectorals" + label_max="Sunken Chest" value_default="0" - value_min="-.5" - value_max="2" - camera_angle="60" - camera_distance=".6"> - <param_morph /> + value_min="-0.5" + value_max="1.1" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="-0.03 -0.024 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="-0.03 0.024 -0.01"/> + </param_morph> </param> - <!-- - ############# - # other morphs (not user controlled) - ############# - --> + <!-- ############# # + other morphs (not user controlled) + ############# --> <param - id="153" + id="100" group="1" - name="Male_Legs" - wearable="shape" + name="Male_Torso" + wearable="shape" edit_group="driven" + label_min="Male_Torso" value_min="0" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="CHEST" + scale="0.03 0.04 0.02" + pos="-0.03 0 -0.01"/> + <volume_morph + name="BELLY" + scale="0.03 0.03 0.0" + pos="-0.03 0 0.02"/> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.008 -0.03 0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.008 0.03 0.01"/> + <volume_morph + name="L_CLAVICLE" + scale="0.02 0.0 0.01" + pos="-0.02 0 0"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.0 0.0 -0.005"/> + <volume_morph + name="R_CLAVICLE" + scale="0.02 0.0 0.01" + pos="-0.02 0 0"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.0 0.0 -0.005"/> + <volume_morph + name="NECK" + scale="0.015 0.01 0.0"/> + <volume_morph + name="HEAD" + scale="0.0 0.0 0.01" + pos="0 0 -0.01"/> + </param_morph> </param> <!-- - ############# - # physics morphs (not user controlled) - ############# + ############## + # animatable morphs + ############## --> <param - id="1202" + id="101" group="1" - name="Belly_Physics_Legs_UpDown_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_min="-1" + name="Hands_Relaxed" + value_min="0" value_max="1"> <param_morph /> </param> - <param - id="1205" + id="102" group="1" - name="Butt_Physics_UpDown_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_default="0" - value_min="-1" + name="Hands_Point" + value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BUTT" - pos="0.0 0.0 0.05"/> - </param_morph> + <param_morph /> </param> <param - id="1206" + id="103" group="1" - name="Butt_Physics_LeftRight_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_default="0" - value_min="-1" + name="Hands_Fist" + value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BUTT" - pos="0.0 0.05 0.0"/> - </param_morph> + <param_morph /> </param> - <!-- - #end morph targets - --> - - </mesh> - - <mesh - type="lowerBodyMesh" - lod="1" - file_name="avatar_lower_body_1.llm" - min_pixel_width="160" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="2" - file_name="avatar_lower_body_2.llm" - min_pixel_width="80" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="3" - file_name="avatar_lower_body_3.llm" - min_pixel_width="40" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="4" - file_name="avatar_lower_body_4.llm" - min_pixel_width="0" - reference="avatar_lower_body.llm"> - </mesh> - - <!-- - #lowerBodyMesh2 = - #lowerBodyMesh3 = - --> - <!-- - #eyeLidLeftMesh = - --> - <mesh - type="eyeBallLeftMesh" - lod="0" - file_name="avatar_eye.llm" - min_pixel_width="320"> - <!-- begin morph_params --> <param - id="679" + id="666" group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> + name="Hands_Relaxed_L" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="687" + id="667" group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> + name="Hands_Point_L" + value_min="0" + value_max="1"> <param_morph /> </param> - </mesh> - <mesh - type="eyeBallLeftMesh" - lod="1" - file_name="avatar_eye_1.llm" - min_pixel_width="80"> - <!-- begin morph_params --> <param - id="694" + id="668" group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> - - <param - id="695" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> - <param_morph /> - </param> - </mesh> - - <!-- - #eyeLidRightMesh = - --> - <mesh - type="eyeBallRightMesh" - lod="0" - file_name="avatar_eye.llm" - min_pixel_width="320"> - <!-- begin morph_params --> - <param - id="680" - group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> - - <param - id="688" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> + name="Hands_Fist_L" + value_min="0" + value_max="1"> <param_morph /> </param> - </mesh> - <mesh - type="eyeBallRightMesh" - lod="1" - file_name="avatar_eye_1.llm" - min_pixel_width="80"> - <!-- begin morph_params --> <param - id="681" + id="669" group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> + name="Hands_Relaxed_R" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="691" + id="670" group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> + name="Hands_Point_R" + value_min="0" + value_max="1"> <param_morph /> </param> - </mesh> - <mesh - type="skirtMesh" - lod="0" - file_name="avatar_skirt.llm" - min_pixel_width="320"> <param - id="845" + id="671" group="1" - name="skirt_poofy" - label="poofy skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="less poofy" - label_max="more poofy" + name="Hands_Fist_R" value_min="0" - value_max="1.5"> + value_max="1"> <param_morph /> </param> <param - id="846" + id="672" group="1" - name="skirt_loose" - label="loose skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + name="Hands_Typing" value_min="0" value_max="1"> <param_morph /> </param> <param - id="866" + id="766" group="1" - name="skirt_tight" - label="tight skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + name="Hands_Salute_R" value_min="0" value_max="1"> <param_morph /> </param> <param - id="867" + id="791" group="1" - name="skirt_smallbutt" - label="tight skirt" - clothing_morph="false" - wearable="skirt" - edit_group="skirt" - cross_wearable="true" - label_min="form fitting" - label_max="loose" + name="Hands_Peace_R" value_min="0" value_max="1"> <param_morph /> </param> <param - id="848" - group="0" - name="skirt_bustle" - label="bustle skirt" - clothing_morph="true" - wearable="skirt" - edit_group_order="3" - edit_group="skirt" - label_min="no bustle" - label_max="more bustle" + id="792" + group="1" + name="Hands_Spread_R" value_min="0" - value_max="2" - value_default=".2" - camera_angle="100" - camera_distance="1.3" - camera_elevation="-.5"> + value_max="1"> <param_morph /> </param> + <!-- + ############# + # physics morphs (not user controlled) + ############# + --> <param - id="847" + id="1200" group="1" - name="skirt_bowlegs" - label="legs skirt" - wearable="skirt" + sex="female" + name="Breast_Physics_UpDown_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - value_min="-1" - value_max="1" - value_default="0"> - <param_morph /> + value_default="0" + value_min="-3" + value_max="3"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.0 -0.01"/> + </param_morph> </param> <param - id="852" + id="1201" group="1" - name="skirt_bigbutt" - wearable="skirt" + sex="female" + name="Breast_Physics_InOut_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - label="bigbutt skirt" - label_min="less" - label_max="more" - value_min="0" - value_max="1"> - <param_morph /> + value_default="0" + value_min="-1.25" + value_max="1.25"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 -0.026 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.026 -0.0"/> + </param_morph> </param> <param - id="849" + id="1204" group="1" - name="skirt_belly" - wearable="skirt" + name="Belly_Physics_Torso_UpDown_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - label="big belly skirt" - value_min="0" + value_default="0" + value_min="-1" value_max="1"> - <param_morph /> - </param> - - <param - id="850" - group="1" - wearable="skirt" - edit_group="driven" - cross_wearable="true" - name="skirt_saddlebags" - value_min="-.5" - value_max="3"> - <param_morph /> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 0.0 0.0" + pos="0.0 0.0 0.05"/> + </param_morph> </param> <param - id="851" + id="1207" group="1" - name="skirt_chubby" - wearable="skirt" + name="Breast_Physics_LeftRight_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - label_min="less" - label_max="more" - value_min="0" - value_max="1" - value_default="0"> - <param_morph /> - </param> - - <param - id="856" - group="1" - name="skirt_lovehandles" - wearable="skirt" - edit_group="driven" - cross_wearable="true" - label_min="less" - label_max="more" - value_min="-1" - value_max="2" - value_default="0"> - <param_morph /> - </param> - - <!-- - ############# - # other morphs (not user controlled) - ############# - --> - <param - id="857" - group="1" - name="skirt_male" - wearable="skirt" - edit_group="driven" - cross_wearable="true" - value_min="0" - value_max="1"> - <param_morph /> + value_default="0" + value_min="-2" + value_max="2"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.03 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.03 0.0"/> + </param_morph> </param> <!-- - ############# - # physics morphs (not user controlled) - ############# - --> - <param - id="1203" - group="1" - name="Belly_Physics_Skirt_UpDown_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_default="0" - value_min="-1" - value_max="1"> - <param_morph /> - </param> + #end morph targets + --> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="1" - file_name="avatar_skirt_1.llm" + file_name="avatar_upper_body_1.llm" min_pixel_width="160" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="2" - file_name="avatar_skirt_2.llm" + file_name="avatar_upper_body_2.llm" min_pixel_width="80" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="3" - file_name="avatar_skirt_3.llm" + file_name="avatar_upper_body_3.llm" min_pixel_width="40" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="4" - file_name="avatar_skirt_4.llm" + file_name="avatar_upper_body_4.llm" min_pixel_width="0" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> - <!-- =========================================================== --> - <global_color - name="skin_color"> + <!-- + #upperBodyMesh2 = + #upperBodyMesh3 = + --> + <mesh + type="lowerBodyMesh" + lod="0" + file_name="avatar_lower_body.llm" + min_pixel_width="320"> + <!-- + #begin morph targets + ############# + # tweakable morphs + ############# + --> <param - id="111" - group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="1" - name="Pigment" - show_simple="true" - label_min="Light" - label_max="Dark" + id="156" + group="1" + name="Big_Belly_Legs" + wearable="shape" + edit_group="driven" value_min="0" - value_max="1" - value_default=".5"> - <param_color> - <value - color="252, 215, 200, 255" /> - - <value - color="240, 177, 112, 255" /> - - <value - color="90, 40, 16, 255" /> - - <value - color="29, 9, 6, 255" /> - </param_color> + value_max="1"> + <param_morph /> </param> + <param - id="110" - group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="2" - name="Red Skin" - label="Ruddiness" - label_min="Pale" - label_max="Ruddy" + id="151" + group="1" + name="Big_Butt_Legs" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + label_min="Regular" + label_max="Large" value_min="0" - value_max="0.1"> - <param_color - operation="blend"> - <value - color="218, 41, 37, 255" /> - </param_color> + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.03 0.0 0.02" + pos="-0.03 0 -0.025"/> + </param_morph> </param> <param - id="108" - group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="3" - name="Rainbow Color" - show_simple="true" - label_min="None" - label_max="Wild" + id="794" + group="1" + name="Small_Butt" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + label_min="Regular" + label_max="Small" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color=" 0, 0, 0, 255" /> - - <value - color="255, 0, 255, 255" /> - - <value - color="255, 0, 0, 255" /> - - <value - color="255, 255, 0, 255" /> - - <value - color=" 0, 255, 0, 255" /> - - <value - color=" 0, 255, 255, 255" /> - - <value - color=" 0, 0, 255, 255" /> - - <value - color="255, 0, 255, 255" /> - </param_color> + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="-0.01 0.0 0.0" + pos="0.01 0 0.0"/> + <volume_morph + name="BUTT" + scale="0.0 0.0886 0.0" + pos="0.03 0 0.0"/> + </param_morph> </param> - </global_color> - <!-- =========================================================== --> - <global_color - name="hair_color"> <param - id="114" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="3" - name="Blonde Hair" + id="152" + group="1" + name="Muscular_Legs" + label="Leg Muscles" show_simple="true" - label_min="Black" - label_max="Blonde" + wearable="shape" + edit_group="shape_legs" + label_min="Regular Muscles" + label_max="More Muscles" value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="22, 6, 6, 255" /> - - <value - color="29, 9, 6, 255" /> - - <value - color="45, 21, 11, 255" /> - - <value - color="78, 39, 11, 255" /> - - <value - color="90, 53, 16, 255" /> - - <value - color="136, 92, 21, 255" /> - - <value - color="150, 106, 33, 255" /> - - <value - color="198, 156, 74, 255" /> + value_max="1.5" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + scale="0.015 0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="0.01 0.01 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="0.015 0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="0.01 0.01 0.0" + pos="0.0 0 0.0"/> + </param_morph> + </param> - <value - color="233, 192, 103, 255" /> + <param + id="651" + group="1" + name="Scrawny_Legs" + label="Scrawny Leg" + wearable="shape" + edit_group="shape_legs" + label_min="Regular Muscles" + label_max="Less Muscles" + value_min="0" + value_max="1.5" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + scale="-0.03 -0.03 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="-0.015 -0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="-0.03 -0.03 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="-0.015 -0.015 0.0" + pos="0.0 0 0.0"/> + </param_morph> + </param> - <value - color="238, 205, 136, 255" /> - </param_color> + <param + id="853" + group="1" + name="Bowed_Legs" + label="Knee Angle" + wearable="shape" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + pos="0.0 0.03 0.0"/> + <volume_morph + name="L_LOWER_LEG" + pos="0.0 0.03 0.0"/> + <volume_morph + name="R_UPPER_LEG" + pos="0.0 -0.03 0.0"/> + <volume_morph + name="R_LOWER_LEG" + pos="0.0 -0.03 0.0"/> + </param_morph> </param> <param - id="113" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="4" - name="Red Hair" - show_simple="true" - label_min="No Red" - label_max="Very Red" + id="500" + group="1" + name="Shoe_Heel_Height" + label="Heel Height" + wearable="shoes" + edit_group="shoes" + label_min="Low Heels" + label_max="High Heels" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="118, 47, 19, 255" /> - </param_color> + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> </param> <param - id="115" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="1" - name="White Hair" - show_simple="true" - label_min="No White" - label_max="All White" + id="501" + group="1" + name="Shoe_Platform_Height" + label="Platform Height" + wearable="shoes" + edit_group="shoes" + label_min="Low Platforms" + label_max="High Platforms" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 255, 255, 255" /> - </param_color> + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> </param> <param - id="112" + id="508" group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="2" - name="Rainbow Color" - show_simple="true" - label_min="None" - label_max="Wild" + name="Shoe_Platform_Width" + label="Platform Width" + wearable="shoes" + edit_group="shoes" + edit_group_order="7" + label_min="Narrow" + label_max="Wide" + value_min="-1" + value_max="2" + camera_angle="15" + camera_distance="1.5" + camera_elevation="-1"> + <param_morph /> + </param> + + <param + id="509" + group="1" + name="Shoe_Heel_Point" + label="Heel Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Heels" + label_max="Pointy Heels" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color=" 0, 0, 0, 255" /> - - <value - color="255, 0, 255, 255" /> - - <value - color="255, 0, 0, 255" /> - - <value - color="255, 255, 0, 255" /> - - <value - color=" 0, 255, 0, 255" /> - - <value - color=" 0, 255, 255, 255" /> - - <value - color=" 0, 0, 255, 255" /> - - <value - color="255, 0, 255, 255" /> - </param_color> + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> </param> - </global_color> - <!-- =========================================================== --> - <global_color - name="eye_color"> <param - id="99" - group="0" - wearable="eyes" - edit_group="eyes" - edit_group_order="1" - name="Eye Color" - show_simple="true" - label_min="Natural" - label_max="Unnatural" + id="510" + group="1" + name="Shoe_Heel_Thick" + label="Heel Shape" + wearable="shoes" + edit_group="shoes" + label_min="default Heels" + label_max="Thick Heels" value_min="0" value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".3"> - <!-- default to natural brown eyes--> - <param_color> - <value - color="50, 25, 5, 255" /> + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> - <!-- natural dark brown eyes--> - <value - color="109, 55, 15, 255" /> - - <!-- natural brown eyes--> - <value - color="150, 93, 49, 255" /> - - <!-- natural light brown eyes--> - <value - color="152, 118, 25, 255" /> - - <!--natural hazel eyes--> - <value - color="95, 179, 107, 255" /> - - <!--natural green eyes--> - <value - color="87, 192, 191, 255" /> - - <!--natural aqua eyes--> - <value - color="95, 172, 179, 255" /> - - <!--natural blue eyes--> - <value - color="128, 128, 128, 255" /> - - <!--natural grey eyes--> - <value - color="0, 0, 0, 255" /> - - <!--black eyes--> - <value - color="255, 255, 0, 255" /> - - <!--bright yellow eyes--> - <value - color=" 0, 255, 0, 255" /> - - <!-- bright green eyes--> - <value - color=" 0, 255, 255, 255" /> + <param + id="511" + group="1" + name="Shoe_Toe_Point" + label="Toe Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Toe" + label_max="Pointy Toe" + value_min="0" + value_max="1" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> - <!-- bright cyan eyes--> - <value - color=" 0, 0, 255, 255" /> + <param + id="512" + group="1" + name="Shoe_Toe_Square" + label="Toe Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Toe" + label_max="Square Toe" + value_min="0" + value_max="1" + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> + </param> - <!--bright blue eyes--> - <value - color="255, 0, 255, 255" /> + <param + id="654" + group="0" + name="Shoe_Toe_Thick" + label="Toe Thickness" + wearable="shoes" + edit_group="shoes" + edit_group_order="5" + label_min="Flat Toe" + label_max="Thick Toe" + value_min="0" + value_max="2" + camera_angle="15" + camera_distance="1.5" + camera_elevation="-1"> + <param_morph /> + </param> - <!-- bright violet eyes--> - <value - color="255, 0, 0, 255" /> + <param + id="515" + group="0" + name="Foot_Size" + label="Foot Size" + wearable="shape" + edit_group="shape_legs" + edit_group_order="6" + label_min="Small" + label_max="Big" + value_min="-1" + value_max="3" + camera_angle="45" + camera_distance="1.1" + camera_elevation="-1"> + <param_morph> + <volume_morph + name="L_FOOT" + scale="0.02 0.01 0.0" + pos="0.01 0 0"/> + <volume_morph + name="R_FOOT" + scale="0.02 0.01 0.0" + pos="0.01 0 0"/> + </param_morph> + </param> - <!--bright red eyes--> - </param_color> + <param + id="516" + group="1" + name="Displace_Loose_Lowerbody" + label="Pants Fit" + wearable="pants" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> </param> <param - id="98" + id="625" group="0" - wearable="eyes" - edit_group="eyes" - edit_group_order="2" - name="Eye Lightness" + name="Leg_Pantflair" + label="Cuff Flare" show_simple="true" - label_min="Darker" - label_max="Lighter" + wearable="pants" + edit_group="pants" + edit_group_order="3" + clothing_morph="true" + label_min="Tight Cuffs" + label_max="Flared Cuffs" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".3"> - <param_color> - <value - color="0, 0, 0, 0" /> + value_max="1.5" + camera_distance="1.8" + camera_angle="30" + camera_elevation="-.3"> + <param_morph /> + </param> - <value - color="255, 255, 255, 255" /> - </param_color> + <param + id="793" + group="1" + name="Leg_Longcuffs" + label="Longcuffs" + wearable="pants" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="3" + value_default="0"> + <param_morph /> </param> - </global_color> - <!-- =========================================================== --> - <layer_set - body_region="hair" - width="512" - height="512" - clear_alpha="false"> - <layer - name="base" - global_color="hair_color" - write_all_channels="true"> - <texture - local_texture="hair_grain" /> - </layer> + <param + id="638" + group="0" + name="Low_Crotch" + label="Pants Crotch" + wearable="pants" + clothing_morph="true" + edit_group="pants" + edit_group_order="4" + label_min="High and Tight" + label_max="Low and Loose" + value_min="0" + value_max="1.3" + camera_distance="1.2" + camera_angle="-20" + camera_elevation="-.3"> + <param_morph /> + </param> - <layer - name="hair texture alpha layer" - visibility_mask="TRUE"> - <texture - local_texture="hair_grain" /> - </layer> + <param + id="635" + group="1" + name="Fat_Legs" + label="Fat Torso" + wearable="shape" + edit_group="shape_body" + label_min="skinny" + label_max="fat" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.03 0.06 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="0.02 0.02 0.0" + pos="0.0 -0.02 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="0.01 0.01 0.0"/> + <volume_morph + name="L_UPPER_LEG" + scale="0.02 0.02 0.0" + pos="0.0 0.02 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="0.01 0.01 0.0"/> + </param_morph> + </param> - <layer - name="hair alpha" - visibility_mask="TRUE"> - <texture - local_texture="hair_alpha" /> - </layer> - - </layer_set> - <!-- =========================================================== --> + <param + id="854" + group="1" + name="Saddlebags" + wearable="shape" + edit_group="driven" + value_min="-.5" + value_max="3"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.0 0.025 0.0"/> + </param_morph> - <layer_set - body_region="head" - width="512" - height="512"> - <layer - name="head bump base" - fixed_color = "128,128,128,255" - render_pass="bump"> - </layer> + </param> - <layer - name="head bump definition" - render_pass="bump"> - + <param + id="20879" + group="1" + sex="male" + name="Male_Package" + value_min="-.5" + value_max="2"> + <param_morph /> + </param> - <texture - tga_file="bump_head_base.tga" - file_is_mask="FALSE"/> + <!-- + ############# + # other morphs (not user controlled) + ############# + --> + <param + id="153" + group="1" + name="Male_Legs" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="873" - group="1" - wearable="skin" - edit_group="driven" - edit_group_order="12" - name="Bump base" - value_min="0" - value_max="1"> - <param_alpha - domain="0" /> - </param> - </layer> + <!-- + ############# + # physics morphs (not user controlled) + ############# + --> + <param + id="1202" + group="1" + name="Belly_Physics_Legs_UpDown_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_min="-1" + value_max="1"> + <param_morph /> + </param> - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="head_skingrain.tga" /> - </layer> + + <param + id="1205" + group="1" + name="Butt_Physics_UpDown_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="BUTT" + pos="0.0 0.0 0.05"/> + </param_morph> + </param> - <layer - name="headcolor"> - <texture - tga_file="head_color.tga" /> - </layer> + <param + id="1206" + group="1" + name="Butt_Physics_LeftRight_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="BUTT" + pos="0.0 0.05 0.0"/> + </param_morph> + </param> - <layer - name="shadow"> - <texture - tga_file="head_shading_alpha.tga" - file_is_mask="TRUE" /> + <!-- + #end morph targets + --> - <param - id="158" - group="1" - wearable="skin" - name="Shading" - value_min="0" - value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> + </mesh> - <value - color="0, 0, 0, 128" /> - </param_color> - </param> - </layer> + <mesh + type="lowerBodyMesh" + lod="1" + file_name="avatar_lower_body_1.llm" + min_pixel_width="160" + reference="avatar_lower_body.llm"> + </mesh> - <layer - name="highlight"> - <texture - tga_file="head_highlights_alpha.tga" -file_is_mask="TRUE" /> + <mesh + type="lowerBodyMesh" + lod="2" + file_name="avatar_lower_body_2.llm" + min_pixel_width="80" + reference="avatar_lower_body.llm"> + </mesh> + <mesh + type="lowerBodyMesh" + lod="3" + file_name="avatar_lower_body_3.llm" + min_pixel_width="40" + reference="avatar_lower_body.llm"> + </mesh> - <param - id="159" - group="1" - name="Shading" - wearable="skin" - value_min="0" - value_max="1"> - <param_color> - <value -color="255, 255, 255, 0" /> + <mesh + type="lowerBodyMesh" + lod="4" + file_name="avatar_lower_body_4.llm" + min_pixel_width="0" + reference="avatar_lower_body.llm"> + </mesh> + <!-- + #lowerBodyMesh2 = + #lowerBodyMesh3 = + --> + <!-- + #eyeLidLeftMesh = + --> + <mesh + type="eyeBallLeftMesh" + lod="0" + file_name="avatar_eye.llm" + min_pixel_width="320"> + <!-- begin morph_params --> + <param + id="679" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <value - color="255, 255, 255, 64" /> - </param_color> - </param> - </layer> - <layer - name="rosyface"> - <texture - tga_file="rosyface_alpha.tga" - file_is_mask="true" /> + <param + id="687" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <param - id="116" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="4" - name="Rosy Complexion" - label_min="Less Rosy" - label_max="More Rosy" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".07"> - <param_color> - <value - color="198, 71, 71, 0" /> - - <value - color="198, 71, 71, 255" /> - </param_color> - </param> - </layer> + <mesh + type="eyeBallLeftMesh" + lod="1" + file_name="avatar_eye_1.llm" + min_pixel_width="80"> + <!-- begin morph_params --> + <param + id="694" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <layer - name="lips"> - <texture - tga_file="lips_mask.tga" - file_is_mask="true" /> + <param + id="695" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <param - id="117" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="5" - name="Lip Pinkness" - label_min="Darker" - label_max="Pinker" - value_min="0" - value_max="1" - camera_distance=".25"> - <param_color> - <value - color="220, 115, 115, 0" /> + <!-- + #eyeLidRightMesh = + --> + <mesh + type="eyeBallRightMesh" + lod="0" + file_name="avatar_eye.llm" + min_pixel_width="320"> + <!-- begin morph_params --> + <param + id="680" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <value - color="220, 115, 115, 128" /> - </param_color> - </param> - </layer> + <param + id="688" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <layer - name="wrinkles_shading" - render_pass="bump" - fixed_color="0,0,0,100"> - <param - id="118" - group="1" - wearable="skin" - name="Wrinkles" - value_min="0" - value_max="1"> - <param_alpha - tga_file="bump_face_wrinkles.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - </layer> + <mesh + type="eyeBallRightMesh" + lod="1" + file_name="avatar_eye_1.llm" + min_pixel_width="80"> + <!-- begin morph_params --> + <param + id="681" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <!--<layer - name="wrinkles_highlights" - fixed_color="255,255,255,64"> - <param - id="128" - group="1" - name="Wrinkles" - value_min="0" - value_max="1"> - <param_alpha - tga_file="head_wrinkles_highlights_alpha.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - </layer>--> - <layer - name="freckles" - fixed_color="120,47,20,128"> - <param - id="165" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="2" - name="Freckles" - label_min="Less" - label_max="More" - value_min="0" - value_max="1" - camera_distance=".3" -camera_elevation=".07"> - <param_alpha - tga_file="freckles_alpha.tga" - skip_if_zero="true" -domain="0.5" /> - </param> - </layer> - <layer -name="eyebrowsbump" -render_pass="bump"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> + <param + id="691" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <param - id="1000" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Size Bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="eyebrows_alpha.tga" - domain="0.1" /> - </param> + <mesh + type="skirtMesh" + lod="0" + file_name="avatar_skirt.llm" + min_pixel_width="320"> + <param + id="845" + group="1" + name="skirt_poofy" + label="poofy skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="less poofy" + label_max="more poofy" + value_min="0" + value_max="1.5"> + <param_morph /> + </param> - <param - id="1002" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Density Bump" - value_min="0" - value_max="1"> - <param_color> - <value - color="255,255,255,0" /> + <param + id="846" + group="1" + name="skirt_loose" + label="loose skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> - - <layer - name="eyebrows" - global_color="hair_color"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> + <param + id="866" + group="1" + name="skirt_tight" + label="tight skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="1001" - group="1" - wearable="hair" - edit_group="hair_eyebrows" - name="Eyebrow Size" - show_simple="true" - value_min="0" - value_max="1" - value_default="0.5"> - <param_alpha - tga_file="eyebrows_alpha.tga" - domain="0.1" /> - </param> + <param + id="867" + group="1" + name="skirt_smallbutt" + label="tight skirt" + clothing_morph="false" + wearable="skirt" + edit_group="skirt" + cross_wearable="true" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="1003" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Density" - value_min="0" - value_max="1"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> + <param + id="848" + group="0" + name="skirt_bustle" + label="bustle skirt" + clothing_morph="true" + wearable="skirt" + edit_group_order="3" + edit_group="skirt" + label_min="no bustle" + label_max="more bustle" + value_min="0" + value_max="2" + value_default=".2" + camera_angle="100" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> + <param + id="847" + group="1" + name="skirt_bowlegs" + label="legs skirt" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + value_min="-1" + value_max="1" + value_default="0"> + <param_morph /> + </param> - <layer - name="lipstick"> - <param - id="700" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="2" - name="Lipstick Color" - label_min="Pink" - label_max="Black" - value_min="0" - value_max="1" - value_default=".25" - camera_distance=".25"> - <param_color> - <value - color="245,161,177,200" /> + <param + id="852" + group="1" + name="skirt_bigbutt" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label="bigbutt skirt" + label_min="less" + label_max="more" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="216,37,67,200" /> + <param + id="849" + group="1" + name="skirt_belly" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label="big belly skirt" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="178,48,76,200" /> + <param + id="850" + group="1" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + name="skirt_saddlebags" + value_min="-.5" + value_max="3"> + <param_morph /> + </param> - <value - color="68,0,11,200" /> + <param + id="851" + group="1" + name="skirt_chubby" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label_min="less" + label_max="more" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> + </param> - <value - color="252,207,184,200" /> + <param + id="856" + group="1" + name="skirt_lovehandles" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label_min="less" + label_max="more" + value_min="-1" + value_max="2" + value_default="0"> + <param_morph /> + </param> - <value - color="241,136,106,200" /> + <!-- + ############# + # other morphs (not user controlled) + ############# + --> + <param + id="857" + group="1" + name="skirt_male" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="208,110,85,200" /> + <!-- + ############# + # physics morphs (not user controlled) + ############# + --> + <param + id="1203" + group="1" + name="Belly_Physics_Skirt_UpDown_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="1"> + <param_morph /> + </param> - <value - color="106,28,18,200" /> + </mesh> - <value - color="58,26,49,200" /> + <mesh + type="skirtMesh" + lod="1" + file_name="avatar_skirt_1.llm" + min_pixel_width="160" + reference="avatar_skirt.llm"> + </mesh> - <value - color="14,14,14,200" /> - </param_color> - </param> + <mesh + type="skirtMesh" + lod="2" + file_name="avatar_skirt_2.llm" + min_pixel_width="80" + reference="avatar_skirt.llm"> + </mesh> - <param - id="701" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="1" - name="Lipstick" - label_min="No Lipstick" - label_max="More Lipstick" - value_min="0" - value_max=".9" - value_default="0.0" - camera_distance=".25"> - <param_alpha - tga_file="lipstick_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - </layer> - - <layer - name="lipgloss" - fixed_color="255,255,255,190"> - <param - id="702" - name="Lipgloss" - label_min="No Lipgloss" - label_max="Glossy" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="3" - group="0" - value_min="0" - value_max="1" - camera_distance=".25"> - <param_alpha - tga_file="lipgloss_alpha.tga" - skip_if_zero="true" - domain="0.2" /> - </param> - </layer> + <mesh + type="skirtMesh" + lod="3" + file_name="avatar_skirt_3.llm" + min_pixel_width="40" + reference="avatar_skirt.llm"> + </mesh> - <layer - name="blush"> - <param - id="704" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="4" - name="Blush" - label_min="No Blush" - label_max="More Blush" - value_min="0" - value_max=".9" - value_default="0" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_alpha - tga_file="blush_alpha.tga" - skip_if_zero="true" - domain="0.3" /> - </param> + <mesh + type="skirtMesh" + lod="4" + file_name="avatar_skirt_4.llm" + min_pixel_width="0" + reference="avatar_skirt.llm"> + </mesh> - <param - id="705" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="5" - name="Blush Color" - label_min="Pink" - label_max="Orange" - value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_color> - <value - color="253,162,193,200" /> + <!-- =========================================================== --> + <global_color + name="skin_color"> + <param + id="111" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="1" + name="Pigment" + show_simple="true" + label_min="Light" + label_max="Dark" + value_min="0" + value_max="1" + value_default=".5"> + <param_color> + <value + color="252, 215, 200, 255" /> - <value - color="247,131,152,200" /> + <value + color="240, 177, 112, 255" /> - <value - color="213,122,140,200" /> + <value + color="90, 40, 16, 255" /> - <value - color="253,152,144,200" /> + <value + color="29, 9, 6, 255" /> + </param_color> + </param> - <value - color="236,138,103,200" /> + <param + id="110" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="2" + name="Red Skin" + label="Ruddiness" + label_min="Pale" + label_max="Ruddy" + value_min="0" + value_max="0.1"> + <param_color + operation="blend"> + <value + color="218, 41, 37, 255" /> + </param_color> + </param> - <value - color="195,128,122,200" /> + <param + id="108" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="3" + name="Rainbow Color" + show_simple="true" + label_min="None" + label_max="Wild" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color=" 0, 0, 0, 255" /> - <value - color="148,103,100,200" /> + <value + color="255, 0, 255, 255" /> - <value - color="168,95,62,200" /> - </param_color> - </param> + <value + color="255, 0, 0, 255" /> - <param - id="711" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="6" - name="Blush Opacity" - label_min="Clear" - label_max="Opaque" - value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> + <value + color="255, 255, 0, 255" /> - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> + <value + color=" 0, 255, 0, 255" /> - <layer - name="Outer Eye Shadow"> - <param - id="708" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="11" - name="Out Shdw Color" - label_min="Light" - label_max="Dark" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="252,247,246,255" /> + <value + color=" 0, 255, 255, 255" /> - <value - color="255,206,206,255" /> + <value + color=" 0, 0, 255, 255" /> - <value - color="233,135,149,255" /> + <value + color="255, 0, 255, 255" /> + </param_color> + </param> + </global_color> - <value - color="220,168,192,255" /> + <!-- =========================================================== --> + <global_color + name="hair_color"> + <param + id="114" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="3" + name="Blonde Hair" + show_simple="true" + label_min="Black" + label_max="Blonde" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="228,203,232,255" /> + <value + color="22, 6, 6, 255" /> - <value - color="255,234,195,255" /> + <value + color="29, 9, 6, 255" /> - <value - color="230,157,101,255" /> + <value + color="45, 21, 11, 255" /> - <value - color="255,147,86,255" /> + <value + color="78, 39, 11, 255" /> - <value - color="228,110,89,255" /> + <value + color="90, 53, 16, 255" /> - <value - color="228,150,120,255" /> + <value + color="136, 92, 21, 255" /> - <value - color="223,227,213,255" /> + <value + color="150, 106, 33, 255" /> - <value - color="96,116,87,255" /> + <value + color="198, 156, 74, 255" /> - <value - color="88,143,107,255" /> + <value + color="233, 192, 103, 255" /> - <value - color="194,231,223,255" /> + <value + color="238, 205, 136, 255" /> + </param_color> + </param> - <value - color="207,227,234,255" /> + <param + id="113" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="4" + name="Red Hair" + show_simple="true" + label_min="No Red" + label_max="Very Red" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="41,171,212,255" /> + <value + color="118, 47, 19, 255" /> + </param_color> + </param> - <value - color="180,137,130,255" /> + <param + id="115" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="1" + name="White Hair" + show_simple="true" + label_min="No White" + label_max="All White" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="173,125,105,255" /> + <value + color="255, 255, 255, 255" /> + </param_color> + </param> - <value - color="144,95,98,255" /> + <param + id="112" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="2" + name="Rainbow Color" + show_simple="true" + label_min="None" + label_max="Wild" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color=" 0, 0, 0, 255" /> - <value - color="115,70,77,255" /> + <value + color="255, 0, 255, 255" /> - <value - color="155,78,47,255" /> + <value + color="255, 0, 0, 255" /> - <value - color="239,239,239,255" /> + <value + color="255, 255, 0, 255" /> - <value - color="194,194,194,255" /> + <value + color=" 0, 255, 0, 255" /> - <value - color="120,120,120,255" /> + <value + color=" 0, 255, 255, 255" /> - <value - color="10,10,10,255" /> - </param_color> - </param> + <value + color=" 0, 0, 255, 255" /> - <param - id="706" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="12" - name="Out Shdw Opacity" - label_min="Clear" - label_max="Opaque" - value_min=".2" - value_max="1" - value_default=".6" - camera_distance=".3" - camera_elevation=".14"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> + <value + color="255, 0, 255, 255" /> + </param_color> + </param> + </global_color> - <value - color="255,255,255,255" /> - </param_color> - </param> + <!-- =========================================================== --> + <global_color + name="eye_color"> + <param + id="99" + group="0" + wearable="eyes" + edit_group="eyes" + edit_group_order="1" + name="Eye Color" + show_simple="true" + label_min="Natural" + label_max="Unnatural" + value_min="0" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".3"> + <!-- default to natural brown eyes--> + <param_color> + <value + color="50, 25, 5, 255" /> - <param - id="707" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="10" - name="Outer Shadow" - label_min="No Eyeshadow" - label_max="More Eyeshadow" - value_min="0" - value_max=".7" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeshadow_outer_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - </layer> + <!-- natural dark brown eyes--> + <value + color="109, 55, 15, 255" /> - <layer - name="Inner Eye Shadow"> - <param - id="712" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="8" - name="In Shdw Color" - label_min="Light" - label_max="Dark" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="252,247,246,255" /> + <!-- natural brown eyes--> + <value + color="150, 93, 49, 255" /> - <value - color="255,206,206,255" /> + <!-- natural light brown eyes--> + <value + color="152, 118, 25, 255" /> - <value - color="233,135,149,255" /> + <!--natural hazel eyes--> + <value + color="95, 179, 107, 255" /> - <value - color="220,168,192,255" /> + <!--natural green eyes--> + <value + color="87, 192, 191, 255" /> - <value - color="228,203,232,255" /> + <!--natural aqua eyes--> + <value + color="95, 172, 179, 255" /> - <value - color="255,234,195,255" /> + <!--natural blue eyes--> + <value + color="128, 128, 128, 255" /> - <value - color="230,157,101,255" /> + <!--natural grey eyes--> + <value + color="0, 0, 0, 255" /> - <value - color="255,147,86,255" /> + <!--black eyes--> + <value + color="255, 255, 0, 255" /> - <value - color="228,110,89,255" /> + <!--bright yellow eyes--> + <value + color=" 0, 255, 0, 255" /> - <value - color="228,150,120,255" /> + <!-- bright green eyes--> + <value + color=" 0, 255, 255, 255" /> - <value - color="223,227,213,255" /> + <!-- bright cyan eyes--> + <value + color=" 0, 0, 255, 255" /> - <value - color="96,116,87,255" /> + <!--bright blue eyes--> + <value + color="255, 0, 255, 255" /> - <value - color="88,143,107,255" /> + <!-- bright violet eyes--> + <value + color="255, 0, 0, 255" /> - <value - color="194,231,223,255" /> + <!--bright red eyes--> + </param_color> + </param> - <value - color="207,227,234,255" /> + <param + id="98" + group="0" + wearable="eyes" + edit_group="eyes" + edit_group_order="2" + name="Eye Lightness" + show_simple="true" + label_min="Darker" + label_max="Lighter" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".3"> + <param_color> + <value + color="0, 0, 0, 0" /> - <value - color="41,171,212,255" /> + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + </global_color> - <value - color="180,137,130,255" /> + <!-- =========================================================== --> + <layer_set + body_region="hair" + width="512" + height="512" + clear_alpha="false"> + <layer + name="base" + global_color="hair_color" + write_all_channels="true"> + <texture + local_texture="hair_grain" /> + </layer> - <value - color="173,125,105,255" /> + <layer + name="hair texture alpha layer" + visibility_mask="TRUE"> + <texture + local_texture="hair_grain" /> + </layer> - <value - color="144,95,98,255" /> + <layer + name="hair alpha" + visibility_mask="TRUE"> + <texture + local_texture="hair_alpha" /> + </layer> - <value - color="115,70,77,255" /> + </layer_set> + <!-- =========================================================== --> - <value - color="155,78,47,255" /> + <layer_set + body_region="head" + width="512" + height="512"> + <layer + name="head bump base" + fixed_color = "128,128,128,255" + render_pass="bump"> + </layer> + + <layer + name="head bump definition" + render_pass="bump"> + + + <texture + tga_file="bump_head_base.tga" + file_is_mask="FALSE"/> + + <param + id="873" + group="1" + wearable="skin" + edit_group="driven" + edit_group_order="12" + name="Bump base" + value_min="0" + value_max="1"> + <param_alpha + domain="0" /> + </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="head_skingrain.tga" /> + </layer> + + <layer + name="headcolor"> + <texture + tga_file="head_color.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="head_shading_alpha.tga" + file_is_mask="TRUE" /> + <param + id="158" + group="1" + wearable="skin" + name="Shading" + value_min="0" + value_max="1"> + <param_color> <value - color="239,239,239,255" /> + color="0, 0, 0, 0" /> <value - color="194,194,194,255" /> + color="0, 0, 0, 128" /> + </param_color> + </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="head_highlights_alpha.tga" +file_is_mask="TRUE" /> + + <param + id="159" + group="1" + name="Shading" + wearable="skin" + value_min="0" + value_max="1"> + <param_color> <value - color="120,120,120,255" /> +color="255, 255, 255, 0" /> + <value - color="10,10,10,255" /> + color="255, 255, 255, 64" /> </param_color> </param> + </layer> + <layer + name="rosyface"> + <texture + tga_file="rosyface_alpha.tga" + file_is_mask="true" /> <param - id="713" + id="116" group="0" wearable="skin" - edit_group="skin_makeup" - edit_group_order="9" - name="In Shdw Opacity" - label_min="Clear" - label_max="Opaque" - value_min=".2" + edit_group="skin_facedetail" + edit_group_order="4" + name="Rosy Complexion" + label_min="Less Rosy" + label_max="More Rosy" + value_min="0" value_max="1" - value_default=".7" camera_distance=".3" - camera_elevation=".14"> - <param_color - operation="multiply"> + camera_elevation=".07"> + <param_color> <value - color="255,255,255,0" /> + color="198, 71, 71, 0" /> <value - color="255,255,255,255" /> + color="198, 71, 71, 255" /> </param_color> </param> + </layer> + + <layer + name="lips"> + <texture + tga_file="lips_mask.tga" + file_is_mask="true" /> <param - id="709" + id="117" group="0" wearable="skin" - edit_group="skin_makeup" - edit_group_order="7" - name="Inner Shadow" - label_min="No Eyeshadow" - label_max="More Eyeshadow" + edit_group="skin_facedetail" + edit_group_order="5" + name="Lip Pinkness" + label_min="Darker" + label_max="Pinker" value_min="0" value_max="1" - value_default="0" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeshadow_inner_alpha.tga" - skip_if_zero="true" - domain="0.2" /> + camera_distance=".25"> + <param_color> + <value + color="220, 115, 115, 0" /> + + <value + color="220, 115, 115, 128" /> + </param_color> </param> </layer> <layer - name="eyeliner" - fixed_color="0,0,0,200"> + name="wrinkles_shading" + render_pass="bump" + fixed_color="0,0,0,100"> <param - id="703" - group="0" + id="118" + group="1" wearable="skin" - edit_group="skin_makeup" - edit_group_order="13" - name="Eyeliner" - label_min="No Eyeliner" - label_max="Full Eyeliner" + name="Wrinkles" value_min="0" - value_max="1" - value_default="0.0" - camera_distance=".3" - camera_elevation=".14"> + value_max="1"> <param_alpha - tga_file="eyeliner_alpha.tga" + tga_file="bump_face_wrinkles.tga" skip_if_zero="true" - domain="0.1" /> + domain="0.3" /> </param> + </layer> + <!--<layer + name="wrinkles_highlights" + fixed_color="255,255,255,64"> + <param + id="128" + group="1" + name="Wrinkles" + value_min="0" + value_max="1"> + <param_alpha + tga_file="head_wrinkles_highlights_alpha.tga" + skip_if_zero="true" + domain="0.3" /> + </param> + </layer>--> + <layer + name="freckles" + fixed_color="120,47,20,128"> <param - id="714" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="14" - name="Eyeliner Color" - label_min="Dark Green" - label_max="Black" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="24,98,40,250" /> - - <!-- dark green --> - <value - color="9,100,127,250" /> - - <!-- lt.aqua blue --> - <value - color="61,93,134,250" /> - - <!-- aqua --> - <value - color="70,29,27,250" /> - - <!-- dark brown --> - <value - color="115,75,65,250" /> - - <!-- lt. brown blue --> - <value - color="100,100,100,250" /> - - <!-- grey --> - <value - color="91,80,74,250" /> - - <!-- grey/brown --> - <value - color="112,42,76,250" /> - - <!-- plum --> - <value - color="14,14,14,250" /> - - <!-- black --> - </param_color> + id="165" + group="0" + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="2" + name="Freckles" + label_min="Less" + label_max="More" + value_min="0" + value_max="1" + camera_distance=".3" +camera_elevation=".07"> + <param_alpha + tga_file="freckles_alpha.tga" + skip_if_zero="true" +domain="0.5" /> </param> </layer> - <layer - name="facialhair bump" - render_pass="bump"> +name="eyebrowsbump" +render_pass="bump"> <texture tga_file="head_hair.tga" file_is_mask="false" /> <param - id="1004" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Sideburns bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_sideburns_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1006" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Moustache bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_moustache_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1008" - sex="male" + id="1000" group="1" wearable="hair" edit_group="driven" - name="Soulpatch bump" + name="Eyebrow Size Bump" value_min="0" value_max="1"> <param_alpha - tga_file="facehair_soulpatch_alpha.tga" - skip_if_zero="true" + tga_file="eyebrows_alpha.tga" domain="0.1" /> </param> <param - id="1010" - sex="male" - group="1" - edit_group="driven" - wearable="hair" - name="Chin Curtains bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_chincurtains_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="1012" + id="1002" group="1" - sex="male" wearable="hair" edit_group="driven" - name="5 O'Clock Shadow bump" + name="Eyebrow Density Bump" value_min="0" value_max="1"> <param_color> <value - color="255,255,255,255" /> + color="255,255,255,0" /> <value - color="255,255,255,0" /> + color="255,255,255,255" /> </param_color> </param> </layer> <layer - name="facialhair" + name="eyebrows" global_color="hair_color"> - <texture tga_file="head_hair.tga" file_is_mask="false" /> <param - id="1005" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Sideburns" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_sideburns_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1007" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Moustache" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_moustache_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1009" - sex="male" + id="1001" group="1" wearable="hair" - edit_group="driven" - name="Soulpatch" + edit_group="hair_eyebrows" + name="Eyebrow Size" + show_simple="true" value_min="0" - value_max="1"> + value_max="1" + value_default="0.5"> <param_alpha - tga_file="facehair_soulpatch_alpha.tga" - skip_if_zero="true" + tga_file="eyebrows_alpha.tga" domain="0.1" /> </param> <param - id="1011" - sex="male" + id="1003" group="1" wearable="hair" edit_group="driven" - name="Chin Curtains" + name="Eyebrow Density" value_min="0" value_max="1"> - <param_alpha - tga_file="facehair_chincurtains_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="751" - group="1" - wearable="hair" - sex="male" - edit_group="hair_facial" - name="5 O'Clock Shadow" - label_min="Dense hair" - label_max="Shadow hair" - value_min="0" - value_max="1" - value_default="0.7" - camera_elevation=".1" - camera_distance=".3"> <param_color operation="multiply"> <value - color="255,255,255,255" /> + color="255,255,255,0" /> <value - color="255,255,255,30" /> + color="255,255,255,255" /> </param_color> </param> </layer> <layer - name="head_bodypaint"> - <texture - local_texture="head_bodypaint" /> - </layer> - <layer - name="eyelash alpha" - visibility_mask="TRUE"> - <texture - tga_file="head_alpha.tga" - file_is_mask="TRUE" /> - </layer> - <layer - name="head alpha" - visibility_mask="TRUE"> - <texture - local_texture="head_alpha" /> - </layer> - <layer - name="head_tattoo"> - <texture - local_texture="head_tattoo" /> + name="lipstick"> <param - id="1062" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_head_red" + id="700" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="2" + name="Lipstick Color" + label_min="Pink" + label_max="Black" value_min="0" value_max="1" - value_default="1"> + value_default=".25" + camera_distance=".25"> <param_color> <value - color="0, 0, 0, 255" /> + color="245,161,177,200" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="216,37,67,200" /> - <param - id="1063" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_head_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="178,48,76,200" /> <value - color="0, 255, 0, 255" /> - </param_color> - </param> + color="68,0,11,200" /> - <param - id="1064" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_head_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="252,207,184,200" /> <value - color="0, 0, 255, 255" /> - </param_color> - </param> + color="241,136,106,200" /> - </layer> + <value + color="208,110,85,200" /> + <value + color="106,28,18,200" /> - </layer_set> + <value + color="58,26,49,200" /> - <!-- =========================================================== --> - <layer_set - body_region="upper_body" - width="512" - height="512"> - <layer - name="base_upperbody bump" - render_pass="bump" - fixed_color="128,128,128,255"> - </layer> - <layer - name="upperbody bump definition" - render_pass="bump"> - <texture - tga_file="bump_upperbody_base.tga" - file_is_mask="FALSE"/> + <value + color="14,14,14,200" /> + </param_color> + </param> <param - id="874" - group="1" + id="701" + group="0" wearable="skin" - edit_group="driven" - edit_group_order="20" - name="Bump upperdef" + edit_group="skin_makeup" + edit_group_order="1" + name="Lipstick" + label_min="No Lipstick" + label_max="More Lipstick" value_min="0" - value_max="1"> + value_max=".9" + value_default="0.0" + camera_distance=".25"> <param_alpha - domain="0" /> + tga_file="lipstick_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> </layer> <layer - name="base" - global_color="skin_color"> - <texture - tga_file="body_skingrain.tga" /> - </layer> - - <layer - name="nipples"> - <texture - tga_file="upperbody_color.tga" /> + name="lipgloss" + fixed_color="255,255,255,190"> + <param + id="702" + name="Lipgloss" + label_min="No Lipgloss" + label_max="Glossy" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="3" + group="0" + value_min="0" + value_max="1" + camera_distance=".25"> + <param_alpha + tga_file="lipgloss_alpha.tga" + skip_if_zero="true" + domain="0.2" /> + </param> </layer> <layer - name="shadow"> - <texture - tga_file="upperbody_shading_alpha.tga" - file_is_mask="TRUE" /> + name="blush"> + <param + id="704" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="4" + name="Blush" + label_min="No Blush" + label_max="More Blush" + value_min="0" + value_max=".9" + value_default="0" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> + <param_alpha + tga_file="blush_alpha.tga" + skip_if_zero="true" + domain="0.3" /> + </param> <param - id="125" - group="1" - name="Shading" + id="705" + group="0" wearable="skin" + edit_group="skin_makeup" + edit_group_order="5" + name="Blush Color" + label_min="Pink" + label_max="Orange" value_min="0" - value_max="1"> + value_max="1" + value_default=".5" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> <param_color> <value - color="0, 0, 0, 0" /> + color="253,162,193,200" /> <value - color="0, 0, 0, 128" /> + color="247,131,152,200" /> + + <value + color="213,122,140,200" /> + + <value + color="253,152,144,200" /> + + <value + color="236,138,103,200" /> + + <value + color="195,128,122,200" /> + + <value + color="148,103,100,200" /> + + <value + color="168,95,62,200" /> </param_color> </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="upperbody_highlights_alpha.tga" - file_is_mask="TRUE" /> <param - id="126" - group="1" + id="711" + group="0" wearable="skin" - name="Shading" + edit_group="skin_makeup" + edit_group_order="6" + name="Blush Opacity" + label_min="Clear" + label_max="Opaque" value_min="0" - value_max="1"> - <param_color> + value_max="1" + value_default=".5" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> + <param_color + operation="multiply"> <value - color="255, 255, 255, 0" /> + color="255,255,255,0" /> <value - color="255, 255, 255, 64" /> + color="255,255,255,255" /> </param_color> </param> </layer> <layer - name="upper_bodypaint"> - <texture - local_texture="upper_bodypaint" /> - </layer> - - <layer - name="freckles upper" - fixed_color="120,47,20,128"> + name="Outer Eye Shadow"> <param - id="776" - group="1" - name="freckles upper" + id="708" + group="0" wearable="skin" - value_min="0" - value_max="1"> - <param_alpha - tga_file="upperbodyfreckles_alpha.tga" - skip_if_zero="true" - domain="0.6" /> - </param> - </layer> - - <layer - name="upper_tattoo"> - <texture - local_texture="upper_tattoo" /> - - <param - id="1065" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_upper_red" + edit_group="skin_makeup" + edit_group_order="11" + name="Out Shdw Color" + label_min="Light" + label_max="Dark" value_min="0" value_max="1" - value_default="1"> + camera_distance=".3" + camera_elevation=".14"> <param_color> <value - color="0, 0, 0, 255" /> + color="252,247,246,255" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="255,206,206,255" /> - <param - id="1066" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_upper_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="233,135,149,255" /> <value - color="0, 255, 0, 255" /> - </param_color> - </param> + color="220,168,192,255" /> - <param - id="1067" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_upper_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="228,203,232,255" /> <value - color="0, 0, 255, 255" /> - </param_color> - </param> + color="255,234,195,255" /> - </layer> + <value + color="230,157,101,255" /> + <value + color="255,147,86,255" /> - <layer - name="upper_undershirt bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_undershirt" - local_texture_alpha_only="true" /> + <value + color="228,110,89,255" /> - <param - id="1043" - group="1" - wearable="undershirt" - edit_group="driven" - name="Sleeve Length bump" - value_min=".01" - value_max="1" - value_default=".4"> - <param_alpha - tga_file="shirt_sleeve_alpha.tga" - multiply_blend="false" - domain="0.01" /> - </param> + <value + color="228,150,120,255" /> - <param - id="1045" - group="1" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="2" - name="Bottom bump" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_bottom_alpha.tga" - multiply_blend="true" - domain="0.05" /> + <value + color="223,227,213,255" /> + + <value + color="96,116,87,255" /> + + <value + color="88,143,107,255" /> + + <value + color="194,231,223,255" /> + + <value + color="207,227,234,255" /> + + <value + color="41,171,212,255" /> + + <value + color="180,137,130,255" /> + + <value + color="173,125,105,255" /> + + <value + color="144,95,98,255" /> + + <value + color="115,70,77,255" /> + + <value + color="155,78,47,255" /> + + <value + color="239,239,239,255" /> + + <value + color="194,194,194,255" /> + + <value + color="120,120,120,255" /> + + <value + color="10,10,10,255" /> + </param_color> </param> <param - id="1047" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Front bump" - value_min="0" + id="706" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="12" + name="Out Shdw Opacity" + label_min="Clear" + label_max="Opaque" + value_min=".2" value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_alpha.tga" - multiply_blend="true" - domain="0.05" /> + value_default=".6" + camera_distance=".3" + camera_elevation=".14"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> + + <value + color="255,255,255,255" /> + </param_color> </param> <param - id="1049" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Back bump" + id="707" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="10" + name="Outer Shadow" + label_min="No Eyeshadow" + label_max="More Eyeshadow" value_min="0" - value_max="1" - value_default=".8"> + value_max=".7" + camera_distance=".3" + camera_elevation=".14"> <param_alpha - tga_file="shirt_collar_back_alpha.tga" - multiply_blend="true" + tga_file="eyeshadow_outer_alpha.tga" + skip_if_zero="true" domain="0.05" /> </param> </layer> <layer - name="upper_undershirt"> - <texture - local_texture="upper_undershirt" /> - + name="Inner Eye Shadow"> <param - id="821" + id="712" group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_red" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="8" + name="In Shdw Color" + label_min="Light" + label_max="Dark" value_min="0" value_max="1" - value_default="1"> + camera_distance=".3" + camera_elevation=".14"> <param_color> <value - color="0, 0, 0, 255" /> + color="252,247,246,255" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="255,206,206,255" /> - <param - id="822" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="233,135,149,255" /> <value - color="0, 255, 0, 255" /> - </param_color> - </param> + color="220,168,192,255" /> - <param - id="823" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="228,203,232,255" /> <value - color="0, 0, 255, 255" /> - </param_color> - </param> + color="255,234,195,255" /> - <param - id="1042" - group="1" - wearable="undershirt" - edit_group="driven" - name="Sleeve Length" - value_min=".01" - value_max="1" - value_default=".4"> - <param_alpha - tga_file="shirt_sleeve_alpha.tga" - multiply_blend="false" - domain="0.01" /> - </param> + <value + color="230,157,101,255" /> - <param - id="1044" - group="1" - wearable="undershirt" - edit_group="driven" - name="Bottom" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_bottom_alpha.tga" - multiply_blend="true" - domain="0.05" /> + <value + color="255,147,86,255" /> + + <value + color="228,110,89,255" /> + + <value + color="228,150,120,255" /> + + <value + color="223,227,213,255" /> + + <value + color="96,116,87,255" /> + + <value + color="88,143,107,255" /> + + <value + color="194,231,223,255" /> + + <value + color="207,227,234,255" /> + + <value + color="41,171,212,255" /> + + <value + color="180,137,130,255" /> + + <value + color="173,125,105,255" /> + + <value + color="144,95,98,255" /> + + <value + color="115,70,77,255" /> + + <value + color="155,78,47,255" /> + + <value + color="239,239,239,255" /> + + <value + color="194,194,194,255" /> + + <value + color="120,120,120,255" /> + + <value + color="10,10,10,255" /> + </param_color> </param> <param - id="1046" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Front" - value_min="0" + id="713" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="9" + name="In Shdw Opacity" + label_min="Clear" + label_max="Opaque" + value_min=".2" value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_alpha.tga" - multiply_blend="true" - domain="0.05" /> + value_default=".7" + camera_distance=".3" + camera_elevation=".14"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> + + <value + color="255,255,255,255" /> + </param_color> </param> <param - id="1048" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Back" - label_min="Low" - label_max="High" + id="709" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="7" + name="Inner Shadow" + label_min="No Eyeshadow" + label_max="More Eyeshadow" value_min="0" value_max="1" - value_default=".8"> + value_default="0" + camera_distance=".3" + camera_elevation=".14"> <param_alpha - tga_file="shirt_collar_back_alpha.tga" - multiply_blend="true" - domain="0.05" /> + tga_file="eyeshadow_inner_alpha.tga" + skip_if_zero="true" + domain="0.2" /> </param> </layer> <layer - name="Nail Polish"> + name="eyeliner" + fixed_color="0,0,0,200"> <param - id="710" + id="703" group="0" wearable="skin" edit_group="skin_makeup" - edit_group_order="15" - name="Nail Polish" - label_min="No Polish" - label_max="Painted Nails" + edit_group_order="13" + name="Eyeliner" + label_min="No Eyeliner" + label_max="Full Eyeliner" value_min="0" value_max="1" value_default="0.0" - camera_distance="1.6" - camera_elevation="-.4" - camera_angle="70"> + camera_distance=".3" + camera_elevation=".14"> <param_alpha - tga_file="nailpolish_alpha.tga" + tga_file="eyeliner_alpha.tga" skip_if_zero="true" domain="0.1" /> </param> <param - id="715" + id="714" group="0" wearable="skin" edit_group="skin_makeup" - edit_group_order="16" - name="Nail Polish Color" - label_min="Pink" + edit_group_order="14" + name="Eyeliner Color" + label_min="Dark Green" label_max="Black" value_min="0" value_max="1" - camera_distance="1.6" - camera_elevation="-.4" - camera_angle="70"> + camera_distance=".3" + camera_elevation=".14"> <param_color> <value - color="255,187,200,255" /> + color="24,98,40,250" /> + <!-- dark green --> <value - color="194,102,127,255" /> + color="9,100,127,250" /> + <!-- lt.aqua blue --> <value - color="227,34,99,255" /> + color="61,93,134,250" /> + <!-- aqua --> <value - color="168,41,60,255" /> + color="70,29,27,250" /> + <!-- dark brown --> <value - color="97,28,59,255" /> + color="115,75,65,250" /> + <!-- lt. brown blue --> <value - color="234,115,93,255" /> + color="100,100,100,250" /> + <!-- grey --> <value - color="142,58,47,255" /> + color="91,80,74,250" /> + <!-- grey/brown --> <value - color="114,30,46,255" /> + color="112,42,76,250" /> + <!-- plum --> <value - color="14,14,14,255" /> + color="14,14,14,250" /> + + <!-- black --> </param_color> </param> </layer> <layer - name="upper_gloves bump" - render_pass="bump" - fixed_color="128,128,128,255"> + name="facialhair bump" + render_pass="bump"> <texture - local_texture="upper_gloves" - local_texture_alpha_only="true" /> + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="1059" + id="1004" + sex="male" group="1" - wearable="gloves" + wearable="hair" edit_group="driven" - name="Glove Length bump" - value_min=".01" - value_max="1" - value_default=".8"> + name="Sideburns bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="glove_length_alpha.tga" - domain="0.01" /> + tga_file="facehair_sideburns_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - id="1061" + id="1006" + sex="male" group="1" - wearable="gloves" + wearable="hair" edit_group="driven" - name="Glove Fingers bump" - value_min=".01" - value_max="1" - value_default="1"> + name="Moustache bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="gloves_fingers_alpha.tga" - multiply_blend="true" - domain="0.01" /> + tga_file="facehair_moustache_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> - </layer> - - <layer - name="upper_gloves"> - <texture - local_texture="upper_gloves" /> <param - id="827" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="829" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="830" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1058" + id="1008" + sex="male" group="1" - wearable="gloves" + wearable="hair" edit_group="driven" - name="Glove Length" - value_min=".01" - value_max="1" - value_default=".8"> + name="Soulpatch bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="glove_length_alpha.tga" - domain="0.01" /> + tga_file="facehair_soulpatch_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> <param - id="1060" + id="1010" + sex="male" group="1" - wearable="gloves" edit_group="driven" - name="Glove Fingers" - value_min=".01" - value_max="1" - value_default="1"> + wearable="hair" + name="Chin Curtains bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="gloves_fingers_alpha.tga" - multiply_blend="true" - domain="0.01" /> + tga_file="facehair_chincurtains_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> - </layer> - - <layer - name="upper_clothes_shadow"> - <texture - local_texture="upper_shirt" /> <param - id="899" + id="1012" group="1" + sex="male" + wearable="hair" edit_group="driven" - wearable="shirt" - name="Upper Clothes Shading" + name="5 O'Clock Shadow bump" value_min="0" - value_max="1" - value_default="0"> + value_max="1"> <param_color> <value - color="0, 0, 0, 0" /> + color="255,255,255,255" /> <value - color="0, 0, 0, 80" /> + color="255,255,255,0" /> </param_color> </param> + </layer> - <param - id="900" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Shadow" - value_min="0.02" - value_max=".87" - value_default="0.02"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> + <layer + name="facialhair" + global_color="hair_color"> + + <texture + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="901" + id="1005" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Shirt Shadow Bottom" - value_min="0.02" + name="Sideburns" + value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" + tga_file="facehair_sideburns_alpha.tga" skip_if_zero="true" domain="0.05" /> </param> <param - id="902" + id="1007" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Collar Front Shadow Height" - value_min="0.02" + name="Moustache" + value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" + tga_file="facehair_moustache_alpha.tga" skip_if_zero="true" - domain="0.02" /> + domain="0.05" /> </param> <param - id="903" + id="1009" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Collar Back Shadow Height" - value_min="0.02" + name="Soulpatch" + value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" + tga_file="facehair_soulpatch_alpha.tga" skip_if_zero="true" - domain="0.02" /> - </param> - </layer> - - <layer - name="upper_shirt base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_shirt" - local_texture_alpha_only="true" /> - - <param - id="1029" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> + domain="0.1" /> </param> <param - id="1030" + id="1011" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Shirt Bottom Cloth" + name="Chin Curtains" value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> + tga_file="facehair_chincurtains_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> <param - id="1031" + id="751" group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" + wearable="hair" + sex="male" + edit_group="hair_facial" + name="5 O'Clock Shadow" + label_min="Dense hair" + label_max="Shadow hair" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> + value_max="1" + value_default="0.7" + camera_elevation=".1" + camera_distance=".3"> + <param_color + operation="multiply"> + <value + color="255,255,255,255" /> - <param - id="1032" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> + <value + color="255,255,255,30" /> + </param_color> </param> </layer> <layer - name="upper_clothes bump" - render_pass="bump"> - <texture - tga_file="bump_shirt_wrinkles.tga" /> - + name="head_bodypaint"> <texture - local_texture="upper_shirt" - local_texture_alpha_only="true" /> - - <param - id="868" - group="3" - wearable="shirt" - edit_group="shirt" - edit_group_order="8" - name="Shirt Wrinkles" + local_texture="head_bodypaint" /> + </layer> + <layer + name="eyelash alpha" + visibility_mask="TRUE"> + <texture + tga_file="head_alpha.tga" + file_is_mask="TRUE" /> + </layer> + <layer + name="head alpha" + visibility_mask="TRUE"> + <texture + local_texture="head_alpha" /> + </layer> + <layer + name="head_tattoo"> + <texture + local_texture="head_tattoo" /> + <param + id="1062" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_head_red" value_min="0" value_max="1" - value_default="0"> + value_default="1"> <param_color> <value - color="255, 255, 255, 0" /> + color="0, 0, 0, 255" /> <value - color="255, 255, 255, 255" /> + color="255, 0, 0, 255" /> </param_color> </param> <param - id="1013" + id="1063" group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_head_green" value_min="0" - value_max="0.85"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="1014" + id="1064" group="1" - wearable="shirt" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_head_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="upper_body" + width="512" + height="512"> + <layer + name="base_upperbody bump" + render_pass="bump" + fixed_color="128,128,128,255"> + </layer> + <layer + name="upperbody bump definition" + render_pass="bump"> + <texture + tga_file="bump_upperbody_base.tga" + file_is_mask="FALSE"/> + + <param + id="874" + group="1" + wearable="skin" edit_group="driven" - name="Shirt Bottom Cloth" + edit_group_order="20" + name="Bump upperdef" value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> + domain="0" /> + </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="body_skingrain.tga" /> + </layer> + + <layer + name="nipples"> + <texture + tga_file="upperbody_color.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="upperbody_shading_alpha.tga" + file_is_mask="TRUE" /> + + <param + id="125" + group="1" + name="Shading" + wearable="skin" + value_min="0" + value_max="1"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 128" /> + </param_color> </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="upperbody_highlights_alpha.tga" + file_is_mask="TRUE" /> <param - id="1015" + id="126" group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" + wearable="skin" + name="Shading" value_min="0" value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 64" /> + </param_color> </param> + </layer> + + <layer + name="upper_bodypaint"> + <texture + local_texture="upper_bodypaint" /> + </layer> + <layer + name="freckles upper" + fixed_color="120,47,20,128"> <param - id="1016" + id="776" group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" + name="freckles upper" + wearable="skin" value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> + tga_file="upperbodyfreckles_alpha.tga" + skip_if_zero="true" + domain="0.6" /> </param> </layer> <layer - name="upper_clothes"> + name="upper_tattoo"> <texture - local_texture="upper_shirt" /> + local_texture="upper_tattoo" /> <param - id="803" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_red" + id="1065" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_upper_red" value_min="0" value_max="1" value_default="1"> @@ -7812,11 +10165,11 @@ render_pass="bump"> </param> <param - id="804" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_green" + id="1066" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_upper_green" value_min="0" value_max="1" value_default="1"> @@ -7830,11 +10183,11 @@ render_pass="bump"> </param> <param - id="805" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_blue" + id="1067" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_upper_blue" value_min="0" value_max="1" value_default="1"> @@ -7847,278 +10200,336 @@ render_pass="bump"> </param_color> </param> + </layer> + + + <layer + name="upper_undershirt bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_undershirt" + local_texture_alpha_only="true" /> + <param - id="600" + id="1043" group="1" - wearable="shirt" + wearable="undershirt" edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85" - value_default=".7"> + name="Sleeve Length bump" + value_min=".01" + value_max="1" + value_default=".4"> <param_alpha - multiply_blend="false" tga_file="shirt_sleeve_alpha.tga" + multiply_blend="false" domain="0.01" /> </param> <param - id="601" + id="1045" group="1" - wearable="shirt" - edit_group="driven" - name="Shirt Bottom Cloth" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="2" + name="Bottom bump" value_min="0" value_max="1" value_default=".8"> <param_alpha - multiply_blend="true" tga_file="shirt_bottom_alpha.tga" + multiply_blend="true" domain="0.05" /> </param> <param - id="602" + id="1047" group="1" - wearable="shirt" + wearable="undershirt" edit_group="driven" - name="Collar Front Height Cloth" + name="Collar Front bump" value_min="0" value_max="1" value_default=".8"> <param_alpha - multiply_blend="true" tga_file="shirt_collar_alpha.tga" + multiply_blend="true" domain="0.05" /> </param> <param - id="778" + id="1049" group="1" - wearable="shirt" + wearable="undershirt" edit_group="driven" - name="Collar Back Height Cloth" + name="Collar Back bump" value_min="0" value_max="1" value_default=".8"> <param_alpha - multiply_blend="true" tga_file="shirt_collar_back_alpha.tga" + multiply_blend="true" domain="0.05" /> </param> </layer> <layer - name="upper_jacket base bump" - render_pass="bump" - fixed_color="128,128,128,255"> + name="upper_undershirt"> <texture - local_texture="upper_jacket" - local_texture_alpha_only="true" /> + local_texture="upper_undershirt" /> <param - id="1039" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="1" - name="Jacket Sleeve Length bump" + id="821" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_red" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="1040" - group="1" - wearable="jacket" - edit_group="driven" - name="Jacket Collar Front bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="1041" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="3.5" - name="Jacket Collar Back bump" + id="822" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_green" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="1037" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length upper bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="1038" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open upper bump" + id="823" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_blue" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper_jacket bump" - render_pass="bump"> - <texture - tga_file="bump_shirt_wrinkles.tga" /> - - <texture - local_texture="upper_jacket" - local_texture_alpha_only="true" /> - - - <param - id="875" - group="1" - wearable="jacket" - name="jacket upper Wrinkles" - value_min="0" - value_max="1" - value_default="0"> + value_max="1" + value_default="1"> <param_color> <value - color="255, 255, 255, 0" /> + color="0, 0, 0, 255" /> <value - color="255, 255, 255, 255" /> + color="0, 0, 255, 255" /> </param_color> </param> <param - id="1019" + id="1042" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - edit_group_order="1" - name="Jacket Sleeve Length bump" - value_min="0" - value_max="1"> + name="Sleeve Length" + value_min=".01" + value_max="1" + value_default=".4"> <param_alpha - multiply_blend="false" tga_file="shirt_sleeve_alpha.tga" + multiply_blend="false" domain="0.01" /> </param> <param - id="1021" + id="1044" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - name="Jacket Collar Front bump" + name="Bottom" value_min="0" - value_max="1"> + value_max="1" + value_default=".8"> <param_alpha + tga_file="shirt_bottom_alpha.tga" multiply_blend="true" - tga_file="shirt_collar_alpha.tga" domain="0.05" /> </param> <param - id="1023" + id="1046" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - edit_group_order="3.5" - name="Jacket Collar Back bump" + name="Collar Front" value_min="0" - value_max="1"> + value_max="1" + value_default=".8"> <param_alpha + tga_file="shirt_collar_alpha.tga" multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" domain="0.05" /> </param> <param - id="1025" + id="1048" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - name="jacket bottom length upper bump" + name="Collar Back" + label_min="Low" + label_max="High" value_min="0" - value_max="1"> + value_max="1" + value_default=".8"> <param_alpha + tga_file="shirt_collar_back_alpha.tga" multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> + domain="0.05" /> </param> + </layer> + <layer + name="Nail Polish"> <param - id="1026" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open upper bump" + id="710" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="15" + name="Nail Polish" + label_min="No Polish" + label_max="Painted Nails" value_min="0" - value_max="1"> + value_max="1" + value_default="0.0" + camera_distance="1.6" + camera_elevation="-.4" + camera_angle="70"> <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> + tga_file="nailpolish_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> - </layer> - - <layer - name="upper_jacket"> - <texture - local_texture="upper_jacket" /> <param - id="831" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_red" + id="715" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="16" + name="Nail Polish Color" + label_min="Pink" + label_max="Black" value_min="0" value_max="1" - value_default="1"> + camera_distance="1.6" + camera_elevation="-.4" + camera_angle="70"> <param_color> <value - color="0, 0, 0, 255" /> + color="255,187,200,255" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="194,102,127,255" /> + + <value + color="227,34,99,255" /> + + <value + color="168,41,60,255" /> + + <value + color="97,28,59,255" /> + + <value + color="234,115,93,255" /> + + <value + color="142,58,47,255" /> + + <value + color="114,30,46,255" /> + + <value + color="14,14,14,255" /> + </param_color> + </param> + </layer> + + <layer + name="upper_gloves bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_gloves" + local_texture_alpha_only="true" /> <param - id="832" + id="1059" group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_green" + wearable="gloves" + edit_group="driven" + name="Glove Length bump" + value_min=".01" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="glove_length_alpha.tga" + domain="0.01" /> + </param> + + <param + id="1061" + group="1" + wearable="gloves" + edit_group="driven" + name="Glove Fingers bump" + value_min=".01" + value_max="1" + value_default="1"> + <param_alpha + tga_file="gloves_fingers_alpha.tga" + multiply_blend="true" + domain="0.01" /> + </param> + </layer> + + <layer + name="upper_gloves"> + <texture + local_texture="upper_gloves" /> + + <param + id="827" + group="0" + wearable="gloves" + edit_group="colorpicker" + name="gloves_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="829" + group="0" + wearable="gloves" + edit_group="colorpicker" + name="gloves_green" value_min="0" value_max="1" value_default="1"> @@ -8132,11 +10543,11 @@ render_pass="bump"> </param> <param - id="833" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_blue" + id="830" + group="0" + wearable="gloves" + edit_group="colorpicker" + name="gloves_blue" value_min="0" value_max="1" value_default="1"> @@ -8150,320 +10561,282 @@ render_pass="bump"> </param> <param - id="1020" + id="1058" group="1" - edit_group="driven" - wearable="jacket" - name="jacket Sleeve Length" value_min="0" - value_max="1"> + wearable="gloves" + edit_group="driven" + name="Glove Length" + value_min=".01" + value_max="1" + value_default=".8"> <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" + tga_file="glove_length_alpha.tga" domain="0.01" /> </param> <param - id="1022" + id="1060" group="1" - wearable="jacket" + wearable="gloves" edit_group="driven" - name="jacket Collar Front" - value_min="0" - value_max="1"> + name="Glove Fingers" + value_min=".01" + value_max="1" + value_default="1"> <param_alpha + tga_file="gloves_fingers_alpha.tga" multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> + domain="0.01" /> </param> + </layer> + + <layer + name="upper_clothes_shadow"> + <texture + local_texture="upper_shirt" /> <param - id="1024" + id="899" group="1" - wearable="jacket" edit_group="driven" - edit_group_order="3.5" - name="jacket Collar Back" + wearable="shirt" + name="Upper Clothes Shading" value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 80" /> + </param_color> + </param> + + <param + id="900" + group="1" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Shadow" + value_min="0.02" + value_max=".87" + value_default="0.02"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + skip_if_zero="true" + domain="0.03" /> + </param> + + <param + id="901" + group="1" + wearable="shirt" + edit_group="driven" + name="Shirt Shadow Bottom" + value_min="0.02" value_max="1"> <param_alpha multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" + tga_file="shirt_bottom_alpha.tga" + skip_if_zero="true" domain="0.05" /> </param> <param - id="620" + id="902" group="1" - wearable="jacket" - edit_group="jacket" - name="bottom length upper" - label_min="hi cut" - label_max="low cut" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + wearable="shirt" + edit_group="driven" + name="Collar Front Shadow Height" + value_min="0.02" + value_max="1"> <param_alpha multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> + tga_file="shirt_collar_alpha.tga" + skip_if_zero="true" + domain="0.02" /> </param> <param - id="622" + id="903" group="1" - wearable="jacket" - edit_group="jacket" - name="open upper" - label_min="closed" - label_max="open" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + wearable="shirt" + edit_group="driven" + name="Collar Back Shadow Height" + value_min="0.02" + value_max="1"> <param_alpha multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> + tga_file="shirt_collar_back_alpha.tga" + skip_if_zero="true" + domain="0.02" /> </param> </layer> <layer - name="upper alpha" - visibility_mask="TRUE"> + name="upper_shirt base bump" + render_pass="bump" + fixed_color="128,128,128,255"> <texture - local_texture="upper_alpha" /> - </layer> + local_texture="upper_shirt" + local_texture_alpha_only="true" /> - </layer_set> - - <!-- =========================================================== --> - <layer_set - body_region="lower_body" - width="512" - height="512"> - <layer - name="lower body bump base" - fixed_color = "128,128,128,255" - render_pass="bump"> - </layer> - <layer - name="base_lowerbody bump" - render_pass="bump"> - <texture - tga_file="bump_lowerbody_base.tga" - file_is_mask="FALSE" /> + <param + id="1029" + group="1" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" + value_min="0" + value_max="0.85"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> + </param> <param - id="878" + id="1030" group="1" - wearable="skin" + wearable="shirt" edit_group="driven" - edit_group_order="20" - name="Bump upperdef" + name="Shirt Bottom Cloth" value_min="0" value_max="1"> <param_alpha - domain="0" /> + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="body_skingrain.tga" /> - </layer> - - <layer - name="shadow"> - <texture - tga_file="lowerbody_shading_alpha.tga" - file_is_mask="TRUE" /> <param - id="160" + id="1031" group="1" - name="Shading" - wearable="pants" - cross_wearable="true" + wearable="shirt" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 128" /> - </param_color> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="lowerbody_highlights_alpha.tga" - file_is_mask="TRUE" /> <param - id="161" + id="1032" group="1" - name="Shading" - wearable="skin" + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" value_min="0" value_max="1"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 64" /> - </param_color> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> </layer> <layer - name="toenails"> - <texture - tga_file="lowerbody_color.tga" /> - </layer> - - <layer - name="lower_bodypaint"> + name="upper_clothes bump" + render_pass="bump"> <texture - local_texture="lower_bodypaint" /> - </layer> - - <layer - name="freckles lower" - fixed_color="120,47,20,128"> - <param - id="777" - group="1" - name="freckles lower" - wearable="skin" - value_min="0" - value_max="1"> - <param_alpha - tga_file="bodyfreckles_alpha.tga" - skip_if_zero="true" - domain="0.6" /> - </param> - </layer> + tga_file="bump_shirt_wrinkles.tga" /> - <layer - name="lower_tattoo"> <texture - local_texture="lower_tattoo" /> + local_texture="upper_shirt" + local_texture_alpha_only="true" /> <param - id="1068" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_lower_red" + id="868" + group="3" + wearable="shirt" + edit_group="shirt" + edit_group_order="8" + name="Shirt Wrinkles" value_min="0" value_max="1" - value_default="1"> + value_default="0"> <param_color> <value - color="0, 0, 0, 255" /> + color="255, 255, 255, 0" /> <value - color="255, 0, 0, 255" /> + color="255, 255, 255, 255" /> </param_color> </param> <param - id="1069" + id="1013" group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_lower_green" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> + value_max="0.85"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="1070" + id="1014" group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_lower_blue" + wearable="shirt" + edit_group="driven" + name="Shirt Bottom Cloth" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="lower_underpants bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_underpants" - local_texture_alpha_only="true" /> - <param - id="1055" + id="1015" group="1" - wearable="underpants" - edit_group="underpants" - name="Pants Length" + wearable="shirt" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" - value_max="1" - value_default=".3"> + value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="1057" + id="1016" group="1" - wearable="underpants" - edit_group="underpants" - name="Pants Waist" + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" value_min="0" - value_max="1" - value_default=".8"> + value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" domain="0.05" /> </param> </layer> <layer - name="lower_underpants"> + name="upper_clothes"> <texture - local_texture="lower_underpants" /> + local_texture="upper_shirt" /> <param - id="824" + id="803" group="0" - wearable="underpants" + wearable="shirt" edit_group="colorpicker" - name="underpants_red" + name="shirt_red" value_min="0" value_max="1" value_default="1"> @@ -8477,11 +10850,11 @@ render_pass="bump"> </param> <param - id="825" + id="804" group="0" - wearable="underpants" + wearable="shirt" edit_group="colorpicker" - name="underpants_green" + name="shirt_green" value_min="0" value_max="1" value_default="1"> @@ -8495,11 +10868,11 @@ render_pass="bump"> </param> <param - id="826" + id="805" group="0" - wearable="underpants" + wearable="shirt" edit_group="colorpicker" - name="underpants_blue" + name="shirt_blue" value_min="0" value_max="1" value_default="1"> @@ -8513,385 +10886,259 @@ render_pass="bump"> </param> <param - id="1054" + id="600" group="1" - wearable="underpants" + wearable="shirt" edit_group="driven" - name="Pants Length" + name="Sleeve Length Cloth" value_min="0" - value_max="1" - value_default=".3" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.3"> + value_max="0.85" + value_default=".7"> <param_alpha - tga_file="pants_length_alpha.tga" + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" domain="0.01" /> </param> <param - id="1056" + id="601" group="1" - wearable="underpants" + wearable="shirt" edit_group="driven" - name="Pants Waist" + name="Shirt Bottom Cloth" value_min="0" value_max="1" value_default=".8"> <param_alpha - tga_file="pants_waist_alpha.tga" + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" domain="0.05" /> </param> - </layer> - - <layer - name="lower_socks bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_socks" - local_texture_alpha_only="true" /> <param - id="1051" + id="602" group="1" - wearable="socks" + wearable="shirt" edit_group="driven" - name="Socks Length bump" + name="Collar Front Height Cloth" value_min="0" value_max="1" - value_default="0.35"> + value_default=".8"> <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_socks"> - <texture - local_texture="lower_socks" /> - - <param - id="818" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="819" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="820" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="1050" + id="778" group="1" - wearable="socks" + wearable="shirt" edit_group="driven" - name="Socks Length bump" + name="Collar Back Height Cloth" value_min="0" value_max="1" - value_default="0.35"> + value_default=".8"> <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> </layer> <layer - name="lower_shoes bump" + name="upper_jacket base bump" render_pass="bump" fixed_color="128,128,128,255"> <texture - local_texture="lower_shoes" + local_texture="upper_jacket" local_texture_alpha_only="true" /> <param - id="1053" + id="1039" group="1" - wearable="shoes" + wearable="jacket" edit_group="driven" - name="Shoe Height bump" + edit_group_order="1" + name="Jacket Sleeve Length bump" value_min="0" - value_max="1" - value_default="0.1"> + value_max="1"> <param_alpha - tga_file="shoe_height_alpha.tga" + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" domain="0.01" /> </param> - </layer> - - <layer - name="lower_shoes"> - <texture - local_texture="lower_shoes" /> <param - id="812" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_red" + id="1040" + group="1" + wearable="jacket" + edit_group="driven" + name="Jacket Collar Front bump" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="813" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_green" + id="1041" + group="1" + wearable="jacket" + edit_group="driven" + edit_group_order="3.5" + name="Jacket Collar Back bump" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="817" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_blue" + id="1037" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket bottom length upper bump" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="1052" + id="1038" group="1" - wearable="shoes" + wearable="jacket" edit_group="driven" - name="Shoe Height" + name="jacket open upper bump" value_min="0" - value_max="1" - value_default="0.1"> + value_max="1"> <param_alpha - tga_file="shoe_height_alpha.tga" + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" domain="0.01" /> </param> </layer> <layer - name="lower_clothes_shadow"> + name="upper_jacket bump" + render_pass="bump"> <texture - local_texture="lower_pants" /> + tga_file="bump_shirt_wrinkles.tga" /> + + <texture + local_texture="upper_jacket" + local_texture_alpha_only="true" /> + <param - id="913" - group="1" - edit_group="driven" - wearable="pants" - name="Lower Clothes Shading" - value_min="0" - value_max="1" - value_default="0"> + id="875" + group="1" + wearable="jacket" + name="jacket upper Wrinkles" + value_min="0" + value_max="1" + value_default="0"> <param_color> <value - color="0, 0, 0, 0" /> + color="255, 255, 255, 0" /> <value - color="0, 0, 0, 80" /> + color="255, 255, 255, 255" /> </param_color> </param> <param - id="914" + id="1019" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Waist Height Shadow" - value_min="0.02" + edit_group_order="1" + name="Jacket Sleeve Length bump" + value_min="0" value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" - skip_if_zero="true" - domain="0.04" /> + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="915" - group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Shadow" - value_min="0.02" - value_max="1"> - <param_alpha - tga_file="pants_length_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - </layer> - - <layer - name="lower_pants base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_pants" - local_texture_alpha_only="true" /> - - <param - id="1035" + id="1021" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Waist Height Cloth" + name="Jacket Collar Front bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" domain="0.05" /> </param> <param - id="1036" + id="1023" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Pants Length Cloth" + edit_group_order="3.5" + name="Jacket Collar Back bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_pants bump" - render_pass="bump"> - <texture - tga_file="bump_pants_wrinkles.tga" /> - - <texture - local_texture="lower_pants" - local_texture_alpha_only="true" /> - - <param - id="869" - group="3" - wearable="pants" - edit_group="pants" - edit_group_order="6" - name="Pants Wrinkles" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="1017" + id="1025" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Waist Height Cloth" + name="jacket bottom length upper bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="1018" + id="1026" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Pants Length Cloth" + name="jacket open upper bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" domain="0.01" /> </param> </layer> <layer - name="lower_pants"> + name="upper_jacket"> <texture - local_texture="lower_pants" /> + local_texture="upper_jacket" /> <param - id="806" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_red" + id="831" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_red" value_min="0" value_max="1" value_default="1"> @@ -8905,11 +11152,11 @@ render_pass="bump"> </param> <param - id="807" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_green" + id="832" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_green" value_min="0" value_max="1" value_default="1"> @@ -8923,11 +11170,11 @@ render_pass="bump"> </param> <param - id="808" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_blue" + id="833" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_blue" value_min="0" value_max="1" value_default="1"> @@ -8941,140 +11188,222 @@ render_pass="bump"> </param> <param - id="614" - group="1" - edit_group="driven" - wearable="pants" - name="Waist Height Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - - <param - id="615" + id="1020" group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Cloth" - value_min="0" - value_max="1" - value_default=".8"> + edit_group="driven" + wearable="jacket" + name="jacket Sleeve Length" value_min="0" + value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" domain="0.01" /> </param> - </layer> - - <layer - name="lower_jacket base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_jacket" - local_texture_alpha_only="true" /> <param - id="1033" + id="1022" group="1" wearable="jacket" edit_group="driven" - cross_wearable="true" - name="jacket bottom length lower bump" + name="jacket Collar Front" value_min="0" value_max="1"> <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" - domain="0.01" /> + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="1034" + id="1024" group="1" wearable="jacket" edit_group="driven" - name="jacket open lower bump" + edit_group_order="3.5" + name="jacket Collar Back" value_min="0" value_max="1"> <param_alpha multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="lower_jacket bump" - render_pass="bump"> - <texture - tga_file="bump_pants_wrinkles.tga" /> - - <texture - local_texture="lower_jacket" - local_texture_alpha_only="true" /> - <param - id="876" + id="620" group="1" wearable="jacket" - name="jacket upper Wrinkles" + edit_group="jacket" + name="bottom length upper" + label_min="hi cut" + label_max="low cut" value_min="0" value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> - </param> - - <param - id="1027" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length lower bump" - value_min="0" - value_max="1"> + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" domain="0.01" /> </param> <param - id="1028" + id="622" group="1" wearable="jacket" - edit_group="driven" - name="jacket open lower bump" + edit_group="jacket" + name="open upper" + label_min="closed" + label_max="open" value_min="0" - value_max="1"> + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> <param_alpha multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" + tga_file="jacket_open_upper_alpha.tga" domain="0.01" /> </param> </layer> <layer - name="lower_jacket"> + name="upper alpha" + visibility_mask="TRUE"> <texture - local_texture="lower_jacket" /> + local_texture="upper_alpha" /> + </layer> - <param - id="809" - group="1" + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="lower_body" + width="512" + height="512"> + <layer + name="lower body bump base" + fixed_color = "128,128,128,255" + render_pass="bump"> + </layer> + <layer + name="base_lowerbody bump" + render_pass="bump"> + <texture + tga_file="bump_lowerbody_base.tga" + file_is_mask="FALSE" /> + + <param + id="878" + group="1" + wearable="skin" + edit_group="driven" + edit_group_order="20" + name="Bump upperdef" + value_min="0" + value_max="1"> + <param_alpha + domain="0" /> + </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="body_skingrain.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="lowerbody_shading_alpha.tga" + file_is_mask="TRUE" /> + + <param + id="160" + group="1" + name="Shading" + wearable="pants" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 128" /> + </param_color> + </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="lowerbody_highlights_alpha.tga" + file_is_mask="TRUE" /> + + <param + id="161" + group="1" + name="Shading" + wearable="skin" + value_min="0" + value_max="1"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 64" /> + </param_color> + </param> + </layer> + + <layer + name="toenails"> + <texture + tga_file="lowerbody_color.tga" /> + </layer> + + <layer + name="lower_bodypaint"> + <texture + local_texture="lower_bodypaint" /> + </layer> + + <layer + name="freckles lower" + fixed_color="120,47,20,128"> + <param + id="777" + group="1" + name="freckles lower" + wearable="skin" + value_min="0" + value_max="1"> + <param_alpha + tga_file="bodyfreckles_alpha.tga" + skip_if_zero="true" + domain="0.6" /> + </param> + </layer> + + <layer + name="lower_tattoo"> + <texture + local_texture="lower_tattoo" /> + + <param + id="1068" + group="1" edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_red" + wearable="tattoo" + name="tattoo_lower_red" value_min="0" value_max="1" value_default="1"> @@ -9088,11 +11417,11 @@ render_pass="bump"> </param> <param - id="810" + id="1069" group="1" edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_green" + wearable="tattoo" + name="tattoo_lower_green" value_min="0" value_max="1" value_default="1"> @@ -9106,11 +11435,11 @@ render_pass="bump"> </param> <param - id="811" + id="1070" group="1" edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_blue" + wearable="tattoo" + name="tattoo_lower_blue" value_min="0" value_max="1" value_default="1"> @@ -9123,101 +11452,56 @@ render_pass="bump"> </param_color> </param> + </layer> + + <layer + name="lower_underpants bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_underpants" + local_texture_alpha_only="true" /> + <param - id="621" + id="1055" group="1" - wearable="jacket" - edit_group="jacket" - name="bottom length lower" - label_min="hi cut" - label_max="low cut" + wearable="underpants" + edit_group="underpants" + name="Pants Length" value_min="0" value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + value_default=".3"> <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" + tga_file="pants_length_alpha.tga" domain="0.01" /> </param> <param - id="623" + id="1057" group="1" - wearable="jacket" - edit_group="jacket" - name="open lower" - label_min="open" - label_max="closed" + wearable="underpants" + edit_group="underpants" + name="Pants Waist" value_min="0" value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + value_default=".8"> <param_alpha - multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> </layer> <layer - name="lower alpha" - visibility_mask="TRUE"> - <texture - local_texture="lower_alpha" /> - </layer> - - </layer_set> - - <!-- =========================================================== --> - <layer_set - body_region="eyes" - width="128" - height="128"> - <layer - name="whites"> - <texture - tga_file="eyewhite.tga" /> - </layer> - - <layer - name="iris" - global_color="eye_color"> - <texture - local_texture="eyes_iris" /> - </layer> - - <layer - name="eyes alpha" - visibility_mask="TRUE"> - <texture - local_texture="eyes_alpha" /> - </layer> - - </layer_set> - - <!-- =========================================================== --> - <layer_set - body_region="skirt" - width="512" - height="512" - clear_alpha="false"> - <layer - name="skirt_fabric" - write_all_channels="true"> + name="lower_underpants"> <texture - local_texture="skirt" /> + local_texture="lower_underpants" /> <param - id="921" + id="824" group="0" - wearable="skirt" + wearable="underpants" edit_group="colorpicker" - name="skirt_red" + name="underpants_red" value_min="0" value_max="1" value_default="1"> @@ -9231,11 +11515,11 @@ render_pass="bump"> </param> <param - id="922" + id="825" group="0" - wearable="skirt" + wearable="underpants" edit_group="colorpicker" - name="skirt_green" + name="underpants_green" value_min="0" value_max="1" value_default="1"> @@ -9249,11 +11533,11 @@ render_pass="bump"> </param> <param - id="923" + id="826" group="0" - wearable="skirt" + wearable="underpants" edit_group="colorpicker" - name="skirt_blue" + name="underpants_blue" value_min="0" value_max="1" value_default="1"> @@ -9265,123 +11549,1696 @@ render_pass="bump"> color="0, 0, 255, 255" /> </param_color> </param> - </layer> - <layer - name="skirt_fabric_alpha"> <param - id="858" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="1" - name="Skirt Length" - show_simple="true" - label_min="Short" - label_max="Long" - value_min=".01" + id="1054" + group="1" + wearable="underpants" + edit_group="driven" + name="Pants Length" + value_min="0" value_max="1" - value_default=".4" - simple_percent_min="40" - simple_percent_max="100" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> + value_default=".3" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.3"> <param_alpha - tga_file="skirt_length_alpha.tga" - domain="0" - multiply_blend="true" /> + tga_file="pants_length_alpha.tga" + domain="0.01" /> </param> <param - id="859" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="4" - name="Slit Front" - label_min="Open Front" - label_max="Closed Front" + id="1056" + group="1" + wearable="underpants" + edit_group="driven" + name="Pants Waist" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> + value_default=".8"> <param_alpha - tga_file="skirt_slit_front_alpha.tga" - multiply_blend="true" - domain="0" /> + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> + </layer> + + <layer + name="lower_socks bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_socks" + local_texture_alpha_only="true" /> <param - id="860" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="5" - name="Slit Back" - label_min="Open Back" - label_max="Closed Back" + id="1051" + group="1" + wearable="socks" + edit_group="driven" + name="Socks Length bump" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="160"> + value_default="0.35"> <param_alpha - tga_file="skirt_slit_back_alpha.tga" - multiply_blend="true" - domain="0" /> + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_socks"> + <texture + local_texture="lower_socks" /> <param - id="861" + id="818" group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="6" - name="Slit Left" - label_min="Open Left" - label_max="Closed Left" + wearable="socks" + edit_group="colorpicker" + name="socks_red" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> - <param_alpha - tga_file="skirt_slit_left_alpha.tga" - multiply_blend="true" - domain="0" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="862" + id="819" group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="7" - name="Slit Right" - label_min="Open Right" - label_max="Closed Right" + wearable="socks" + edit_group="colorpicker" + name="socks_green" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="-30"> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="820" + group="0" + wearable="socks" + edit_group="colorpicker" + name="socks_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="1050" + group="1" + wearable="socks" + edit_group="driven" + name="Socks Length bump" + value_min="0" + value_max="1" + value_default="0.35"> <param_alpha - tga_file="skirt_slit_right_alpha.tga" - multiply_blend="true" - domain="0" /> + tga_file="shoe_height_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_shoes bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_shoes" + local_texture_alpha_only="true" /> + + <param + id="1053" + group="1" + wearable="shoes" + edit_group="driven" + name="Shoe Height bump" + value_min="0" + value_max="1" + value_default="0.1"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> </layer> - </layer_set> + <layer + name="lower_shoes"> + <texture + local_texture="lower_shoes" /> + + <param + id="812" + group="0" + wearable="shoes" + edit_group="colorpicker" + name="shoes_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="813" + group="0" + wearable="shoes" + edit_group="colorpicker" + name="shoes_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="817" + group="0" + wearable="shoes" + edit_group="colorpicker" + name="shoes_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="1052" + group="1" + wearable="shoes" + edit_group="driven" + name="Shoe Height" + value_min="0" + value_max="1" + value_default="0.1"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_clothes_shadow"> + <texture + local_texture="lower_pants" /> + + <param + id="913" + group="1" + edit_group="driven" + wearable="pants" + name="Lower Clothes Shading" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 80" /> + </param_color> + </param> + + <param + id="914" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Shadow" + value_min="0.02" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + skip_if_zero="true" + domain="0.04" /> + </param> + + <param + id="915" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Shadow" + value_min="0.02" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + skip_if_zero="true" + domain="0.03" /> + </param> + </layer> + + <layer + name="lower_pants base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_pants" + local_texture_alpha_only="true" /> + + <param + id="1035" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> + + <param + id="1036" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_pants bump" + render_pass="bump"> + <texture + tga_file="bump_pants_wrinkles.tga" /> + + <texture + local_texture="lower_pants" + local_texture_alpha_only="true" /> + + <param + id="869" + group="3" + wearable="pants" + edit_group="pants" + edit_group_order="6" + name="Pants Wrinkles" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + + <param + id="1017" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> + + <param + id="1018" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_pants"> + <texture + local_texture="lower_pants" /> + + <param + id="806" + group="0" + wearable="pants" + edit_group="colorpicker" + name="pants_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="807" + group="0" + wearable="pants" + edit_group="colorpicker" + name="pants_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="808" + group="0" + wearable="pants" + edit_group="colorpicker" + name="pants_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="614" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" + value_min="0" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> + + <param + id="615" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_jacket base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_jacket" + local_texture_alpha_only="true" /> + + <param + id="1033" + group="1" + wearable="jacket" + edit_group="driven" + cross_wearable="true" + name="jacket bottom length lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> + </param> + + <param + id="1034" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket open lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_jacket bump" + render_pass="bump"> + <texture + tga_file="bump_pants_wrinkles.tga" /> + + <texture + local_texture="lower_jacket" + local_texture_alpha_only="true" /> + + + <param + id="876" + group="1" + wearable="jacket" + name="jacket upper Wrinkles" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + + <param + id="1027" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket bottom length lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> + </param> + + <param + id="1028" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket open lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_jacket"> + <texture + local_texture="lower_jacket" /> + + <param + id="809" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="810" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="811" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="621" + group="1" + wearable="jacket" + edit_group="jacket" + name="bottom length lower" + label_min="hi cut" + label_max="low cut" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> + </param> + + <param + id="623" + group="1" + wearable="jacket" + edit_group="jacket" + name="open lower" + label_min="open" + label_max="closed" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower alpha" + visibility_mask="TRUE"> + <texture + local_texture="lower_alpha" /> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="eyes" + width="128" + height="128"> + <layer + name="whites"> + <texture + tga_file="eyewhite.tga" /> + </layer> + + <layer + name="iris" + global_color="eye_color"> + <texture + local_texture="eyes_iris" /> + </layer> + + <layer + name="eyes alpha" + visibility_mask="TRUE"> + <texture + local_texture="eyes_alpha" /> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="skirt" + width="512" + height="512" + clear_alpha="false"> + <layer + name="skirt_fabric" + write_all_channels="true"> + <texture + local_texture="skirt" /> + + <param + id="921" + group="0" + wearable="skirt" + edit_group="colorpicker" + name="skirt_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="922" + group="0" + wearable="skirt" + edit_group="colorpicker" + name="skirt_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="923" + group="0" + wearable="skirt" + edit_group="colorpicker" + name="skirt_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + </layer> + + <layer + name="skirt_fabric_alpha"> + <param + id="858" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="1" + name="Skirt Length" + show_simple="true" + label_min="Short" + label_max="Long" + value_min=".01" + value_max="1" + value_default=".4" + simple_percent_min="40" + simple_percent_max="100" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_length_alpha.tga" + domain="0" + multiply_blend="true" /> + </param> + + <param + id="859" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="4" + name="Slit Front" + label_min="Open Front" + label_max="Closed Front" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_slit_front_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + + <param + id="860" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="5" + name="Slit Back" + label_min="Open Back" + label_max="Closed Back" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="160"> + <param_alpha + tga_file="skirt_slit_back_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + + <param + id="861" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="6" + name="Slit Left" + label_min="Open Left" + label_max="Closed Left" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_slit_left_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + + <param + id="862" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="7" + name="Slit Right" + label_min="Open Right" + label_max="Closed Right" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="-30"> + <param_alpha + tga_file="skirt_slit_right_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <driver_parameters> + + <param + id="2" + group="0" + name="Nose_Big_Out" + label="Nose Size" + wearable="shape" + edit_group="shape_nose" + edit_group_order="1" + label_min="Small" + label_max="Large" + show_simple="true" + value_min="-0.8" + value_max="2.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="50"> + <param_driver> + <driven + id="20002" /> + <driven + id="30002" /> + </param_driver> + </param> + + <param + id="4" + group="0" + name="Broad_Nostrils" + label="Nostril Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="3" + label_min="Narrow" + label_max="Broad" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20004" /> + <driven + id="30004" /> + </param_driver> + </param> + + <param + id="517" + group="0" + name="Wide_Nose" + label="Nose Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="2" + label_min="Narrow" + label_max="Wide" + show_simple="true" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20517" /> + <driven + id="30517" /> + </param_driver> + </param> + + <param + id="20" + group="0" + name="Bulbous_Nose" + label="Nose Thickness" + wearable="shape" + edit_group="shape_nose" + edit_group_order="4" + label_min="Thin Nose" + label_max="Bulbous Nose" + show_simple="true" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="20020" /> + <driven + id="30020" /> + </param_driver> + </param> + + <param + id="656" + group="0" + name="Crooked_Nose" + wearable="shape" + label="Crooked Nose" + edit_group="shape_nose" + edit_group_order="9" + label_min="Nose Left" + label_max="Nose Right" + value_min="-2" + value_max="2" + camera_distance=".3" + camera_elevation=".04" + camera_angle="-20"> + <param_driver> + <driven + id="20656" /> + <driven + id="30656" /> + </param_driver> + </param> + + <param + id="653" + group="0" + name="Tall_Lips" + wearable="shape" + label="Lip Fullness" + show_simple="true" + edit_group="shape_mouth" + edit_group_order="2" + label_min="Less Full" + label_max="More Full" + value_min="-1" + value_max="2" + camera_distance=".3" + camera_elevation=".04"> + <param_driver> + <driven + id="20653" /> + <driven + id="30653" /> + </param_driver> + </param> + + <param + id="506" + group="0" + name="Mouth_Height" + wearable="shape" + label="Mouth Position" + show_simple="true" + edit_group="shape_mouth" + edit_group_order="4" + label_min="High" + label_max="Low" + value_min="-2" + value_max="2" + camera_distance=".3" + camera_elevation=".04"> + <param_driver> + <driven + id="20506" /> + <driven + id="30506" /> + </param_driver> + </param> + + <param + id="764" + group="0" + name="Lip_Cleft_Deep" + label="Lip Cleft Depth" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="5.8" + label_min="Shallow" + label_max="Deep" + value_min="-.5" + value_max="1.2" + camera_elevation="0" + camera_distance=".28"> + <param_driver> + <driven + id="20764" /> + <driven + id="30764" /> + </param_driver> + </param> + + <param + id="25" + group="0" + name="Wide_Lip_Cleft" + label="Lip Cleft" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="6" + label_min="Narrow" + label_max="Wide" + value_min="-.8" + value_max="1.5" + camera_elevation="0" + camera_distance=".28"> + <param_driver> + <driven + id="20025" /> + <driven + id="30025" /> + </param_driver> + </param> + + <param + id="663" + group="0" + name="Shift_Mouth" + wearable="shape" + label="Shift Mouth" + edit_group="shape_mouth" + edit_group_order="7" + label_min="Shift Left" + label_max="Shift Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".35" + camera_elevation=".04" + camera_angle="-20"> + <param_driver> + <driven + id="20663" /> + + <driven + id="31663" + min1="-2" + max1="-2" + max2="-2" + min2="0" /> + <driven + id="32663" + min1="0" + max1="2" + max2="2" + min2="2" /> + </param_driver> + </param> + + <param + id="35" + group="0" + name="Big_Ears" + label="Ear Size" + wearable="shape" + edit_group="shape_ears" + edit_group_order="1" + label_min="Small" + label_max="Large" + value_min="-1" + value_max="2" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_driver> + <driven + id="20035" /> + <driven + id="30035" /> + </param_driver> + </param> + + <param + id="15" + group="0" + name="Ears_Out" + label="Ear Angle" + wearable="shape" + edit_group="shape_ears" + edit_group_order="2" + label_min="In" + label_max="Out" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20015" /> + <driven + id="30015" /> + </param_driver> + </param> + + <param + id="796" + group="0" + name="Pointy_Ears" + label="Ear Tips" + wearable="shape" + edit_group="shape_ears" + edit_group_order="4" + label_min="Flat" + label_max="Pointy" + value_min="-.4" + value_max="3" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_driver> + <driven + id="20796" /> + <driven + id="30796" /> + </param_driver> + </param> + + <param + id="185" + group="0" + name="Deep_Chin" + label="Chin Depth" + wearable="shape" + edit_group="shape_chin" + edit_group_order="3" + label_min="Shallow" + label_max="Deep" + value_min="-1" + value_max="1" + camera_elevation=".1" + camera_distance=".4" + camera_angle="30"> + <param_driver> + <driven + id="20185" /> + <driven + id="30185" /> + </param_driver> + </param> + + <param + id="760" + group="0" + name="Jaw_Angle" + wearable="shape" + label="Jaw Angle" + edit_group="shape_chin" + edit_group_order="3.5" + label_min="Low Jaw" + label_max="High Jaw" + value_min="-1.2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="70"> + <param_driver> + <driven + id="20760" /> + <driven + id="30760" /> + </param_driver> + </param> + + + <param + id="665" + group="0" + name="Jaw_Jut" + wearable="shape" + label="Jaw Jut" + edit_group="shape_chin" + edit_group_order="4" + label_min="Overbite" + label_max="Underbite" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="70"> + <param_driver> + <driven + id="20665" /> + <driven + id="30665" /> + </param_driver> + </param> + + <param + id="6" + group="0" + name="Bulbous_Nose_Tip" + label="Nose Tip Shape" + wearable="shape" + edit_group="shape_nose" + edit_group_order="8" + label_min="Pointy" + label_max="Bulbous" + value_min="-.3" + value_max="1" + camera_elevation=".1" + camera_distance=".35" + camera_angle="15"> + <param_driver> + <driven + id="20006" /> + <driven + id="30006" /> + </param_driver> + </param> + + <param + id="7" + group="0" + name="Weak_Chin" + label="Chin Angle" + wearable="shape" + edit_group="shape_chin" + edit_group_order="1" + label_min="Chin Out" + label_max="Chin In" + value_min="-.5" + value_max=".5" + camera_elevation=".1" + camera_distance=".4" + camera_angle="45"> + <param_driver> + <driven + id="20007" /> + <driven + id="30007" /> + </param_driver> + </param> + + <param + id="8" + group="0" + name="Double_Chin" + label="Chin-Neck" + wearable="shape" + edit_group="shape_chin" + edit_group_order="8" + label_min="Tight Chin" + label_max="Double Chin" + value_min="-.5" + value_max="1.5" + camera_elevation="-.1" + camera_distance=".3" + camera_angle="60"> + <param_driver> + <driven + id="20008" /> + <driven + id="30008" /> + </param_driver> + </param> + + + <param + id="24" + group="0" + name="Wide_Eyes" + label="Eye Opening" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="1.1" + label_min="Narrow" + label_max="Wide" + value_min="-1.5" + value_max="2" + show_simple="true" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20024" /> + <driven + id="30024" /> + </param_driver> + </param> + + <param + id="650" + group="0" + name="Eyelid_Corner_Up" + label="Outer Eye Corner" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="4" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".30"> + <param_driver> + <driven + id="20650" /> + <driven + id="30650" /> + </param_driver> + </param> + + <param + id="880" + group="0" + name="Eyelid_Inner_Corner_Up" + label="Inner Eye Corner" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="4.2" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".30"> + <param_driver> + <driven + id="20880" /> + <driven + id="30880" /> + </param_driver> + </param> + + <param + id="21" + group="0" + name="Upper_Eyelid_Fold" + label="Upper Eyelid Fold" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="5" + label_min="Uncreased" + label_max="Creased" + value_min="-0.2" + value_max="1.3" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20021" /> + <driven + id="30021" /> + </param_driver> + </param> + + <param + id="23" + group="0" + name="Baggy_Eyes" + label="Eye Bags" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="6" + label_min="Smooth" + label_max="Baggy" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20023" /> + <driven + id="30023" /> + </param_driver> + </param> + + <param + id="765" + group="0" + name="Puffy_Lower_Lids" + label="Puffy Eyelids" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="6.1" + label_min="Flat" + label_max="Puffy" + value_min="-.3" + value_max="2.5" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20765" /> + <driven + id="30765" /> + </param_driver> + </param> + + <param + id="1" + group="0" + name="Big_Brow" + label="Brow Size" + wearable="shape" + edit_group="shape_head" + edit_group_order="7" + label_min="Small" + label_max="Large" + value_min="-.3" + value_max="2" + camera_elevation=".1" + camera_distance=".4" + camera_angle="45"> + <param_driver> + <driven + id="20001" /> + <driven + id="30001" /> + </param_driver> + </param> + + <param + id="11" + group="0" + name="Noble_Nose_Bridge" + label="Upper Bridge" + wearable="shape" + edit_group="shape_nose" + edit_group_order="5" + label_min="Low" + label_max="High" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="70"> + <param_driver> + <driven + id="20011" /> + <driven + id="30011" /> + </param_driver> + </param> + + <param + id="758" + group="0" + name="Lower_Bridge_Nose" + label="Lower Bridge" + wearable="shape" + edit_group="shape_nose" + edit_group_order="5.5" + label_min="Low" + label_max="High" + value_min="-1.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="70"> + <param_driver> + <driven + id="20758" /> + <driven + id="30758" /> + </param_driver> + </param> + + <param + id="27" + group="0" + name="Wide_Nose_Bridge" + label="Bridge Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="6" + label_min="Narrow" + label_max="Wide" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20027" /> + <driven + id="30027" /> + </param_driver> + </param> + + <param + id="759" + group="0" + name="Low_Septum_Nose" + label="Nostril Division" + wearable="shape" + edit_group="shape_nose" + edit_group_order="3.5" + label_min="High" + label_max="Low" + value_min="-1" + value_max="1.5" + value_default="0.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20759" /> + <driven + id="30759" /> + </param_driver> + </param> + - <!-- =========================================================== --> - <driver_parameters> + <param + id="10" + group="0" + name="Sunken_Cheeks" + label="Lower Cheeks" + wearable="shape" + edit_group="shape_head" + edit_group_order="9" + label_min="Well-Fed" + label_max="Sunken" + show_simple="true" + value_min="-1.5" + value_max="3" + camera_elevation=".1" + camera_distance=".4" + camera_angle="5"> + <param_driver> + <driven + id="20010" /> + <driven + id="30010" /> + </param_driver> + </param> + + <param + id="17" + group="0" + name="Square_Jaw" + label="Jaw Shape" + wearable="shape" + edit_group="shape_chin" + edit_group_order="2" + label_min="Pointy" + label_max="Square" + value_min="-.5" + value_max="1" + camera_distance=".3" + camera_elevation=".04" + camera_angle="-20"> + <param_driver> + <driven + id="20017" /> + <driven + id="30017" /> + </param_driver> + </param> + + <param + id="18" + group="0" + name="Puffy_Upper_Cheeks" + label="Upper Cheeks" + wearable="shape" + edit_group="shape_head" + edit_group_order="8" + label_min="Thin" + label_max="Puffy" + value_min="-1.5" + value_max="2.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20018" /> + <driven + id="30018" /> + </param_driver> + </param> + + <param + id="14" + group="0" + name="High_Cheek_Bones" + label="Cheek Bones" + wearable="shape" + edit_group="shape_head" + edit_group_order="10" + label_min="Low" + label_max="High" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20014" /> + <driven + id="30014" /> + </param_driver> + </param> + + <param + id="19" + group="0" + name="Upturned_Nose_Tip" + label="Nose Tip Angle" + wearable="shape" + edit_group="shape_nose" + edit_group_order="7" + label_min="Downturned" + label_max="Upturned" + value_min="-1.5" + value_max="1" + camera_elevation=".1" + camera_distance=".35" + camera_angle="15"> + <param_driver> + <driven + id="20019" /> + <driven + id="30019" /> + </param_driver> + </param> <param id="828" @@ -9807,6 +13664,20 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="30505" + min1="0" + max1="0" + max2="0" + min2=".5" /> + <driven + id="31505" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> </param> @@ -9817,8 +13688,8 @@ render_pass="bump"> edit_group="shape_mouth" edit_group_order="3.2" name="Lip Ratio" - label="Lip Ratio" - show_simple="true" + label="Lip Ratio" + show_simple="true" label_min="More Upper Lip" label_max="More Lower Lip" value_min="0" @@ -9841,6 +13712,21 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="30797" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="30798" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> </param> @@ -9866,6 +13752,10 @@ render_pass="bump"> <driven id="30" /> + + <driven + id="30155" /> + </param_driver> </param> @@ -10076,6 +13966,10 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="30193"/> + </param_driver> </param> @@ -10366,8 +14260,8 @@ render_pass="bump"> edit_group="hair_style" edit_group_order="16" name="Hair Tilt" - label_min="Hair Tilted Left" - label_max="Hair Tilted Right" + label_min="Left" + label_max="Right" value_min="0" value_max="1" value_default=".5" @@ -10548,6 +14442,21 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="31629" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="32629" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> </param> @@ -10574,6 +14483,14 @@ render_pass="bump"> <driven id="186" /> + + <driven + min1="-1.3" + max1="-1.3" + max2="-1.3" + min2="1" + id="30646" /> + </param_driver> </param> @@ -10600,6 +14517,10 @@ render_pass="bump"> <driven id="187" /> + + <driven + id="30647" /> + </param_driver> </param> @@ -10630,7 +14551,7 @@ render_pass="bump"> min2=".5" /> <driven - id="106" + id="107" min1=".5" max1="1" max2="1" @@ -10758,8 +14679,23 @@ render_pass="bump"> min1=".5" max1="1" max2="1" + min2="1" /> + + <driven + id="30658" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="30657" + min1=".5" + max1="1" + max2="1" min2="1" /> </param_driver> + </param> <param @@ -10812,6 +14748,24 @@ render_pass="bump"> <driven id="772" /> + + <driven + id="30772" /> + + <driven + min1="0" + max1="0" + max2="0" + min2="0.45" + id="31772" /> + + <driven + min1="0.5" + max1="1" + max2="1" + min2="1" + id="32772" /> + </param_driver> </param> @@ -10822,7 +14776,7 @@ render_pass="bump"> edit_group="shape_head" edit_group_order="1" name="Head Size" - label="Head Size" + label="Head Size" label_min="Small Head" label_max="Big Head" show_simple="true" @@ -10856,16 +14810,17 @@ render_pass="bump"> edit_group="shape_eyes" edit_group_order="1" name="Eye Size" - label="Eye Size" + label="Eye Size" label_min="Beady Eyes" label_max="Anime Eyes" value_min="0" value_max="1" value_default=".5" - show_simple="true" + show_simple="true" camera_elevation=".1" camera_distance=".35"> <param_driver> + <driven id="686" /> @@ -10883,6 +14838,10 @@ render_pass="bump"> <driven id="689" /> + + <driven + id="30689" /> + </param_driver> </param> @@ -11168,6 +15127,31 @@ render_pass="bump"> </param_driver> </param> + <param + id="879" + group="0" + sex="male" + name="Male_Package" + label="Package" + wearable="shape" + edit_group="shape_legs" + edit_group_order="4.6" + label_min="Coin Purse" + label_max="Duffle Bag" + value_default="0" + value_min="-.5" + value_max="2" + camera_angle="60" + camera_distance=".6"> + <param_driver> + <driven + id="20879" /> + + <driven + id="30879" /> + </param_driver> + </param> + <param id="841" group="0" @@ -11302,6 +15286,10 @@ render_pass="bump"> <driven id="1001" /> + + <driven + id="30119" /> + </param_driver> </param> @@ -11766,6 +15754,8 @@ render_pass="bump"> <param_driver> <driven id="870" /> + <driven + id="30016"/> </param_driver> </param> @@ -11789,6 +15779,8 @@ render_pass="bump"> <param_driver> <driven id="871" /> + <driven + id="30757"/> </param_driver> </param> @@ -11811,6 +15803,8 @@ render_pass="bump"> <param_driver> <driven id="872" /> + <driven + id="30031"/> </param_driver> </param> diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 6b07bbc1d3d5fcbac2a50b2eb834f867d81de75d..2241a12545ffd942b86c3ed87422cdceb0ac0798 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -1,81 +1,232 @@ -<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> -<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="26"> -<bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015"> - <collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/> - <collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/> - <bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073"> - <collision_volume name="BELLY" pos = "0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15"/> - <collision_volume name="LOWER_BACK" pos = "0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/> - <collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/> - <collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/> - <bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877"> - <collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/> - <collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/> - <collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/> - <collision_volume name="RIGHT_PEC" pos = "0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/> - <bone name="mNeck" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.009507 0.000000 0.251108"> - <collision_volume name="NECK" pos = "0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08"/> - <bone name="mHead" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.000000 0.075630"> - <collision_volume name="HEAD" pos = "0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12"/> - <bone name="mSkull" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.079000"> - </bone> - <bone name="mEyeRight" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" pivot="0.098466 -0.036000 0.079000"> - </bone> - <bone name="mEyeLeft" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.098461 0.036000 0.079000"> - </bone> - </bone> - </bone> - <bone name="mCollarLeft" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 0.084665 0.165396"> - <collision_volume name="L_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/> - <bone name="mShoulderLeft" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.079000 -0.000000"> - <collision_volume name="L_UPPER_ARM" pos = "0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/> - <bone name="mElbowLeft" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.248000 0.000000"> - <collision_volume name="L_LOWER_ARM" pos = "0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/> - <bone name="mWristLeft" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 0.204846 0.000000"> - <collision_volume name="L_HAND" pos = "0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03"/> - </bone> - </bone> - </bone> - </bone> - <bone name="mCollarRight" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 -0.085000 0.165396"> - <collision_volume name="R_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/> - <bone name="mShoulderRight" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.079418 -0.000000"> - <collision_volume name="R_UPPER_ARM" pos = "0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/> - <bone name="mElbowRight" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.248000 -0.000000"> - <collision_volume name="R_LOWER_ARM" pos = "0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/> - <bone name="mWristRight" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 -0.205000 -0.000000"> - <collision_volume name="R_HAND" pos = "0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03"/> - </bone> - </bone> - </bone> - </bone> - </bone> - </bone> - <bone name="mHipRight" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033620 -0.128806 -0.041086"> - <collision_volume name="R_UPPER_LEG" pos = "-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/> - <bone name="mKneeRight" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000780 0.048635 -0.490922"> - <collision_volume name="R_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/> - <bone name="mAnkleRight" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028869 0.000000 -0.468494"> - <collision_volume name="R_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/> - <bone name="mFootRight" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060637"> - <bone name="mToeRight" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105399 -0.010408 -0.000104"> - </bone> - </bone> - </bone> - </bone> - </bone> - <bone name="mHipLeft" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033757 0.126765 -0.040998"> - <collision_volume name="L_UPPER_LEG" pos = "-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/> - <bone name="mKneeLeft" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000887 -0.045568 -0.491053"> - <collision_volume name="L_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/> - <bone name="mAnkleLeft" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028887 0.001378 -0.468449"> - <collision_volume name="L_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/> - <bone name="mFootLeft" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060620"> - <bone name="mToeLeft" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105387 0.008270 0.000871"> - </bone> - </bone> - </bone> - </bone> - </bone> -</bone> -</linden_skeleton> \ No newline at end of file +<linden_skeleton num_bones="133" num_collision_volumes="26" version="2.0"> + <bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/> + <collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/> + <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> + <collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> + <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/> + <collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="0.080 0.000 -0.006" group="Collision" name="RIGHT_PEC" pos="0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="-0.100 0.000 0.000" group="Collision" name="UPPER_BACK" pos="0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> + <bone aliases="neck avatar_mNeck" connected="true" end="0.000 0.000 0.077" group="Torso" name="mNeck" pivot="-0.009507 0.000000 0.251108" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 0.080" group="Collision" name="NECK" pos="0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08" support="base"/> + <bone aliases="head avatar_mHead" connected="true" end="0.000 0.000 0.079" group="Torso" name="mHead" pivot="0.000000 -0.000000 0.075630" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 0.100" group="Collision" name="HEAD" pos="0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12" support="base"/> + <bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + <bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/> + <bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone aliases="lCollar avatar_mCollarLeft" connected="false" end="0.000 0.079 0.000" group="Arms" name="mCollarLeft" pivot="-0.020927 0.084665 0.165396" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.100 0.000" group="Collision" name="L_CLAVICLE" pos="0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05" support="base"/> + <bone aliases="lShldr avatar_mShoulderLeft" connected="true" end="0.000 0.247 0.000" group="Arms" name="mShoulderLeft" pivot="0.000000 0.079000 -0.000000" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.130 -0.003" group="Collision" name="L_UPPER_ARM" pos="0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05" support="base"/> + <bone aliases="lForeArm avatar_mElbowLeft" connected="true" end="0.000 0.205 0.000" group="Arms" name="mElbowLeft" pivot="0.000000 0.248000 0.000000" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/> + <bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/> + <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone aliases="rCollar avatar_mCollarRight" connected="false" end="0.000 -0.079 0.000" group="Arms" name="mCollarRight" pivot="-0.020927 -0.085000 0.165396" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 -0.100 0.000" group="Collision" name="R_CLAVICLE" pos="0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05" support="base"/> + <bone aliases="rShldr avatar_mShoulderRight" connected="true" end="0.000 -0.247 0.000" group="Arms" name="mShoulderRight" pivot="0.000000 -0.079418 -0.000000" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 -0.130 -0.003" group="Collision" name="R_UPPER_ARM" pos="0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05" support="base"/> + <bone aliases="rForeArm avatar_mElbowRight" connected="true" end="0.000 -0.205 0.000" group="Arms" name="mElbowRight" pivot="0.000000 -0.248000 -0.000000" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/> + <bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/> + <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone aliases="rThigh avatar_mHipRight" connected="false" end="-0.001 0.049 -0.491" group="Legs" name="mHipRight" pivot="0.033620 -0.128806 -0.041086" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 -0.200" group="Collision" name="R_UPPER_LEG" pos="-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32" support="base"/> + <bone aliases="rShin avatar_mKneeRight" connected="true" end="-0.029 0.000 -0.469" group="Legs" name="mKneeRight" pivot="-0.000780 0.048635 -0.490922" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="-0.010 0.000 -0.150" group="Collision" name="R_LOWER_LEG" pos="-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25" support="base"/> + <bone aliases="rFoot avatar_mAnkleRight" connected="true" end="0.112 0.000 -0.061" group="Legs" name="mAnkleRight" pivot="-0.028869 0.000000 -0.468494" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.089 0.000 -0.026" group="Collision" name="R_FOOT" pos="0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05" support="base"/> + <bone aliases="avatar_mFootRight" connected="true" end="0.105 -0.010 0.000" group="Extra" name="mFootRight" pivot="0.111956 -0.000000 -0.060637" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <bone aliases="avatar_mToeRight" connected="false" end="0.020 0.000 0.000" group="Extra" name="mToeRight" pivot="0.105399 -0.010408 -0.000104" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + </bone> + </bone> + </bone> + </bone> + <bone aliases="lThigh avatar_mHipLeft" connected="false" end="-0.001 -0.046 -0.491" group="Legs" name="mHipLeft" pivot="0.033757 0.126765 -0.040998" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 -0.200" group="Collision" name="L_UPPER_LEG" pos="-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32" support="base"/> + <bone aliases="lShin avatar_mKneeLeft" connected="true" end="-0.029 0.001 -0.469" group="Legs" name="mKneeLeft" pivot="-0.000887 -0.045568 -0.491053" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="-0.010 0.000 -0.150" group="Collision" name="L_LOWER_LEG" pos="-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25" support="base"/> + <bone aliases="lFoot avatar_mAnkleLeft" connected="true" end="0.112 0.000 -0.061" group="Legs" name="mAnkleLeft" pivot="-0.028887 0.001378 -0.468449" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.089 0.000 -0.026" group="Collision" name="L_FOOT" pos="0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05" support="base"/> + <bone aliases="avatar_mFootLeft" connected="true" end="0.105 0.008 0.001" group="Extra" name="mFootLeft" pivot="0.111956 -0.000000 -0.060620" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <bone aliases="avatar_mToeLeft" connected="false" end="0.020 0.000 0.000" group="Extra" name="mToeLeft" pivot="0.105387 0.008270 0.000871" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + </bone> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> +</linden_skeleton> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d8b078785212a924bf304f7c04cd1787aef09648..66e2d6fa6afa6f7888581595007a1970c7a9ffa4 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4190,6 +4190,8 @@ void LLAgent::setTeleportState(ETeleportState state) void LLAgent::stopCurrentAnimations() { + LL_DEBUGS("Avatar") << "Stopping current animations" << LL_ENDL; + // This function stops all current overriding animations on this // avatar, propagating this change back to the server. if (isAgentAvatarValid()) @@ -4207,6 +4209,7 @@ void LLAgent::stopCurrentAnimations() // don't cancel a ground-sit anim, as viewers // use this animation's status in // determining whether we're sitting. ick. + LL_DEBUGS("Avatar") << "sit or do-not-disturb animation will not be stopped" << LL_ENDL; } else { @@ -4236,8 +4239,7 @@ void LLAgent::stopCurrentAnimations() // re-assert at least the default standing animation, because // viewers get confused by avs with no associated anims. - sendAnimationRequest(ANIM_AGENT_STAND, - ANIM_REQUEST_START); + sendAnimationRequest(ANIM_AGENT_STAND, ANIM_REQUEST_START); } } diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index fa16f02c16cc154e0c0214871b9b1bda4c204dad..e335eabd1af7bf29e8d2aa217228e6affc5f2386 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1448,6 +1448,7 @@ void LLAgentCamera::updateCamera() diff.mV[VZ] = 0.f; } + // SL-315 gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); gAgentAvatarp->mRoot->updateWorldMatrixChildren(); @@ -2144,6 +2145,7 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate) if (isAgentAvatarValid()) { + // SL-315 gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); gAgentAvatarp->startMotion( ANIM_AGENT_BREATHE_ROT ); @@ -2184,6 +2186,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) { if (!gAgentAvatarp->isSitting()) { + // SL-315 gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); } gAgentAvatarp->startMotion(ANIM_AGENT_BODY_NOISE); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 92e3cd02791ae4c793660910a78acb56213a24e4..4d6d7a9d89e91e7ecb7f722a0cb8958fde4fd87f 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -857,7 +857,7 @@ void LLWearableHoldingPattern::onAllComplete() // attachments, even those that are not being removed. This is // needed to get joint positions all slammed down to their // pre-attachment states. - gAgentAvatarp->clearAttachmentPosOverrides(); + gAgentAvatarp->clearAttachmentOverrides(); if (objects_to_remove.size() || items_to_add.size()) { @@ -880,7 +880,7 @@ void LLWearableHoldingPattern::onAllComplete() ++it) { LLViewerObject *objectp = *it; - gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); + gAgentAvatarp->addAttachmentOverridesForObject(objectp); } // Add new attachments to match those requested. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9db03a74381a9fbd58a485b3cc42ba162f0c1dea..a0ebae119e57f864dccd7a92e40f81c9046c1af5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -99,6 +99,7 @@ #include "llscenemonitor.h" #include "llavatarrenderinfoaccountant.h" #include "lllocalbitmaps.h" +#include "llskinningutil.h" // Linden library includes #include "llavatarnamecache.h" @@ -802,6 +803,9 @@ bool LLAppViewer::init() LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ; + // initialize skinning util + LLSkinningUtil::initClass(); + //set the max heap size. initMaxHeapSize() ; LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); @@ -5860,7 +5864,6 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle) } } - /** * Attempts to start a multi-threaded metrics report to be sent back to * the grid for consumption. @@ -5878,6 +5881,11 @@ void LLAppViewer::metricsSend(bool enable_reporting) { std::string caps_url = regionp->getCapability("ViewerMetrics"); + if (gSavedSettings.getBOOL("QAModeMetrics")) + { + dump_sequential_xml("metric_asset_stats",gViewerAssetStats->asLLSD(true)); + } + // Make a copy of the main stats to send into another thread. // Receiving thread takes ownership. LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats)); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 5431daca32e4ffab26234f4453ecc73afa15aeca..7413dbed20049131d5a6728f0c5be8f778248675 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -354,7 +354,7 @@ void LLAvatarRenderInfoAccountant::resetRenderInfoScanTimer() // are returned for a new LLViewerRegion, and is the earliest time to get render info void LLAvatarRenderInfoAccountant::scanNewRegion(const LLUUID& region_id) { - LL_INFOS("AvatarRenderInfo") << region_id << LL_ENDL; + LL_DEBUGS("AvatarRenderInfo") << region_id << LL_ENDL; // Reset the global timer so it will scan regions on the next call to ::idle LLAvatarRenderInfoAccountant::getInstance()->resetRenderInfoScanTimer(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 4c16c542d6a947ef25a9dca4777fde1f2cfa4903..499cf76bffe384fa463faecfd4344f3122609fa4 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "lldrawpoolavatar.h" +#include "llskinningutil.h" #include "llrender.h" #include "llvoavatar.h" @@ -56,8 +57,6 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; static U32 sBufferUsage = GL_STREAM_DRAW_ARB; static U32 sShaderLevel = 0; -#define JOINT_COUNT 52 - LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL; BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE; BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE; @@ -1461,7 +1460,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } } -void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +void LLDrawPoolAvatar::getRiggedGeometry( + LLFace* face, + LLPointer<LLVertexBuffer>& buffer, + U32 data_mask, + const LLMeshSkinInfo* skin, + LLVolume* volume, + const LLVolumeFace& vol_face) { face->setGeomIndex(0); face->setIndicesIndex(0); @@ -1470,7 +1475,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> face->setTextureIndex(255); if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) - { //make a new buffer + { + // make a new buffer if (sShaderLevel > 0) { buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); @@ -1482,7 +1488,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); } else - { //resize existing buffer + { + //resize existing buffer buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); } @@ -1496,9 +1503,9 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> m = m.inverse().transpose(); F32 mat3[] = - { m.m[0], m.m[1], m.m[2], - m.m[4], m.m[5], m.m[6], - m.m[8], m.m[9], m.m[10] }; + { m.m[0], m.m[1], m.m[2], + m.m[4], m.m[5], m.m[6], + m.m[8], m.m[9], m.m[10] }; LLMatrix3 mat_normal(mat3); @@ -1525,25 +1532,36 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> { face->clearState(LLFace::TEXTURE_ANIM); } - - face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); buffer->flush(); } -void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( + LLVOAvatar* avatar, + LLFace* face, + const LLMeshSkinInfo* skin, + LLVolume* volume, + const LLVolumeFace& vol_face) { - LLVector4a* weight = vol_face.mWeights; - if (!weight) + LLVector4a* weights = vol_face.mWeights; + if (!weights) { return; } + // FIXME ugly const cast + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin)); LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } if (buffer.isNull() || buffer->getTypeMask() != data_mask || @@ -1595,62 +1613,22 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; //build matrix palette - LLMatrix4a mp[JOINT_COUNT]; - LLMatrix4* mat = (LLMatrix4*) mp; - - U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); - for (U32 j = 0; j < count; ++j) - { - LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); - if (!joint) - { - joint = avatar->getJoint("mPelvis"); - } - if (joint) - { - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); - } - } + LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); + const U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; - final_mat.clear(); - - S32 idx[4]; - - LLVector4 wght; - - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j][k]; - - idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)JOINT_COUNT-1); - - wght[k] = w - floorf(w); - scale += wght[k]; - } - // This is enforced in unpackVolumeFaces() - llassert(scale>0.f); - wght *= 1.f/scale; - - for (U32 k = 0; k < 4; k++) - { - F32 w = wght[k]; - - LLMatrix4a src; - src.setMul(mp[idx[k]], w); - - final_mat.add(src); - } - + LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; LLVector4a dst; bind_shape_matrix.affineTransform(v, t); @@ -1728,64 +1706,43 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (buff) { if (sShaderLevel > 0) - { //upload matrix palette to shader - LLMatrix4 mat[JOINT_COUNT]; - - U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); + { + // upload matrix palette to shader + LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - for (U32 i = 0; i < count; ++i) - { - LLJoint* joint = avatar->getJoint(skin->mJointNames[i]); - if (!joint) - { - joint = avatar->getJoint("mPelvis"); - } - if (joint) - { - mat[i] = skin->mInvBindMatrix[i]; - mat[i] *= joint->getWorldMatrix(); - } - } - stop_glerror(); - F32 mp[JOINT_COUNT*9]; - - F32 transp[JOINT_COUNT*3]; + F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; for (U32 i = 0; i < count; ++i) { - F32* m = (F32*) mat[i].mMatrix; + F32* m = (F32*) mat[i].mMatrix[0].getF32ptr(); - U32 idx = i*9; + U32 idx = i*12; mp[idx+0] = m[0]; mp[idx+1] = m[1]; mp[idx+2] = m[2]; + mp[idx+3] = m[12]; - mp[idx+3] = m[4]; - mp[idx+4] = m[5]; - mp[idx+5] = m[6]; - - mp[idx+6] = m[8]; - mp[idx+7] = m[9]; - mp[idx+8] = m[10]; - - idx = i*3; + mp[idx+4] = m[4]; + mp[idx+5] = m[5]; + mp[idx+6] = m[6]; + mp[idx+7] = m[13]; - transp[idx+0] = m[12]; - transp[idx+1] = m[13]; - transp[idx+2] = m[14]; + mp[idx+8] = m[8]; + mp[idx+9] = m[9]; + mp[idx+10] = m[10]; + mp[idx+11] = m[14]; } - LLDrawPoolAvatar::sVertexProgram->uniformMatrix3fv(LLViewerShaderMgr::AVATAR_MATRIX, + LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, count, FALSE, (GLfloat*) mp); - LLDrawPoolAvatar::sVertexProgram->uniform3fv(LLShaderMgr::AVATAR_TRANSLATION, count, transp); - - stop_glerror(); } else diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index cc77b407ae60737e79323d853c06ea61cda11e84..5e0f3ab7f948f1b2659f623216f2b2419fd96410 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -144,7 +144,7 @@ namespace Details int errorCount = 0; int counter = mCounter; // saved on the stack for logging. - LL_INFOS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL; + LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL; mAdapter = httpAdapter; @@ -172,7 +172,7 @@ namespace Details { if (status == LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT)) { // A standard timeout response we get this when there are no events. - LL_INFOS("LLEventPollImpl") << "All is very quiet on target server. It may have gone idle?" << LL_ENDL; + LL_DEBUGS("LLEventPollImpl") << "All is very quiet on target server. It may have gone idle?" << LL_ENDL; errorCount = 0; continue; } @@ -266,7 +266,7 @@ namespace Details } } } - LL_INFOS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL; + LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL; } } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 481c66aaf55d7dff279d29e72796a647b2d35be3..50a4925c37f8e5fc6841bc52b4edb555d63457ca 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -573,6 +573,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) LLRiggedVolume* rigged = volume->getRiggedVolume(); if (rigged) { + // called when selecting a face during edit of a mesh object LLGLEnable offset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.f, -1.f); gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4a059fdc6788efcffa2f0e2dcbd498af9fd6e509..d1e77f57e28c2999d9d35dab9f25a2de82d2fcd3 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -904,7 +904,8 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target base[label]["Samples"].asInteger()); } - exportCharts(baseline, target); + // This currently crashes, possibly due to a race condition in shutdown: + // exportCharts(baseline, target); os.flush(); os.close(); diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index e5df417ca9f89d5d8174c6e61d9be7fd3c4f33a4..d33a138e943e04dcd8c5d60e0ebf355cbed4f5e8 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -178,6 +178,12 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); } +std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases() +{ + LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar(); + return av->getJointAliases(); +} + //----------------------------------------------------------------------------- // postBuild() //----------------------------------------------------------------------------- @@ -215,6 +221,8 @@ BOOL LLFloaterBvhPreview::postBuild() getChildView("bad_animation_text")->setVisible(FALSE); + mAnimPreview = new LLPreviewAnimation(256, 256); + std::string exten = gDirUtilp->getExtension(mFilename); if (exten == "bvh") { @@ -241,8 +249,11 @@ BOOL LLFloaterBvhPreview::postBuild() file_buffer[file_size] = '\0'; LL_INFOS() << "Loading BVH file " << mFilename << LL_ENDL; ELoadStatus load_status = E_ST_OK; - S32 line_number = 0; - loaderp = new LLBVHLoader(file_buffer, load_status, line_number); + S32 line_number = 0; + + std::map<std::string, std::string> joint_alias_map = getJointAliases(); + + loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map); std::string status = getString(STATUS[load_status]); if(load_status == E_ST_NO_XLT_FILE) @@ -266,8 +277,6 @@ BOOL LLFloaterBvhPreview::postBuild() mTransactionID.generate(); mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - mAnimPreview = new LLPreviewAnimation(256, 256); - // motion will be returned, but it will be in a load-pending state, as this is a new motion // this motion will not request an asset transfer until next update, so we have a chance to // load the keyframe data locally @@ -280,9 +289,12 @@ BOOL LLFloaterBvhPreview::postBuild() LLDataPackerBinaryBuffer dp(buffer, buffer_size); // pass animation data through memory buffer + LL_INFOS("BVH") << "Serializing loaderp" << LL_ENDL; loaderp->serialize(dp); dp.reset(); + LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; BOOL success = motionp && motionp->deserialize(dp); + LL_INFOS("BVH") << "Done" << LL_ENDL; delete []buffer; diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index b81cc6e3a51649cbdadeeeef78ad9db0e8bcef88..20d15d96033b35bf4d5c0e383c4a5d74dcd08253 100644 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -109,7 +109,9 @@ class LLFloaterBvhPreview : public LLFloaterNameDesc S32 status, LLExtStat ext_status); private: void setAnimCallbacks() ; - + std::map <std::string, std::string> getJointAliases(); + + protected: void draw(); void resetMotion(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ffeebfd25613a51c94479e3d30c64cc6d64b236e..7aae48cf5da62adb2e27b0b299aa7345eb06f5c0 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -42,7 +42,6 @@ #include "llcombobox.h" #include "lldatapacker.h" #include "lldrawable.h" -#include "lldrawpoolavatar.h" #include "llrender.h" #include "llface.h" #include "lleconomy.h" @@ -54,6 +53,7 @@ #include "llmeshrepository.h" #include "llnotificationsutil.h" #include "llsdutil_math.h" +#include "llskinningutil.h" #include "lltextbox.h" #include "lltoolmgr.h" #include "llui.h" @@ -298,6 +298,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetTextArg("status", "[STATUS]", getString("status_idle")); @@ -311,6 +312,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("upload_skin", onUploadSkinCommit, this); childSetCommitCallback("upload_joints", onUploadJointsCommit, this); + childSetCommitCallback("lock_scale_if_joint_position", onUploadJointsCommit, this); childSetCommitCallback("import_scale", onImportScaleCommit, this); childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); @@ -323,6 +325,7 @@ BOOL LLFloaterModelPreview::postBuild() childDisable("upload_skin"); childDisable("upload_joints"); + childDisable("lock_scale_if_joint_position"); initDecompControls(); @@ -488,11 +491,21 @@ void LLFloaterModelPreview::onClickCalculateBtn() bool upload_skinweights = childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = childGetValue("upload_joints").asBoolean(); + bool lock_scale_if_joint_position = childGetValue("lock_scale_if_joint_position").asBoolean(); + + if (upload_joint_positions) + { + // Diagnostic message showing list of joints for which joint offsets are defined. + // FIXME - given time, would be much better to put this in the UI, in updateStatusMessages(). + mModelPreview->getPreviewAvatar()->showAttachmentOverrides(); + } mUploadModelUrl.clear(); gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, - childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false, + childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, + mUploadModelUrl, false, getWholeModelFeeObserverHandle()); toggleCalculateButton(false); @@ -1190,7 +1203,6 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) , mPhysicsSearchLOD( LLModel::LOD_PHYSICS ) , mResetJoints( false ) , mModelNoErrors( true ) -, mRigParityWithScene( false ) , mLastJointUpdate( false ) { mNeedsUpdate = TRUE; @@ -1317,9 +1329,10 @@ U32 LLModelPreview::calcResourceCost() decomp, mFMP->childGetValue("upload_skin").asBoolean(), mFMP->childGetValue("upload_joints").asBoolean(), + mFMP->childGetValue("lock_scale_if_joint_position").asBoolean(), TRUE, - FALSE, - instance.mModel->mSubmodelID); + FALSE, + instance.mModel->mSubmodelID); num_hulls += decomp.mHull.size(); for (U32 i = 0; i < decomp.mHull.size(); ++i) @@ -1644,27 +1657,23 @@ void LLModelPreview::rebuildUploadData() } -void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position) { if (!mLODFile[LLModel::LOD_HIGH].empty()) { std::string filename = mLODFile[LLModel::LOD_HIGH]; - - std::string::size_type i = filename.rfind("."); - if (i != std::string::npos) - { - filename.replace(i, filename.size()-1, ".slm"); - saveUploadData(filename, save_skinweights, save_joint_positions); + std::string slm_filename; + + if (LLModelLoader::getSLMFilename(filename, slm_filename)) + { + saveUploadData(slm_filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position); } } } -void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(const std::string& filename, + bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position) { - if (!gSavedSettings.getBOOL("MeshImportUseSLM")) - { - return; - } std::set<LLPointer<LLModel> > meshes; std::map<LLModel*, std::string> mesh_binary; @@ -1704,7 +1713,9 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw instance.mLOD[LLModel::LOD_LOW], instance.mLOD[LLModel::LOD_IMPOSTOR], decomp, - save_skinweights, save_joint_positions, + save_skinweights, + save_joint_positions, + lock_scale_if_joint_position, FALSE, TRUE, instance.mModel->mSubmodelID); data["mesh"][instance.mModel->mLocalID] = str.str(); @@ -1731,6 +1742,20 @@ void LLModelPreview::clearModel(S32 lod) mScene[lod].clear(); } +void LLModelPreview::getJointAliases( JointMap& joint_map) +{ + // Get all standard skeleton joints from the preview avatar. + LLVOAvatar *av = getPreviewAvatar(); + + //Joint names and aliases come from avatar_skeleton.xml + + joint_map = av->getJointAliases(); + for (S32 i = 0; i < av->mNumCollisionVolumes; i++) + { + joint_map[av->mCollisionVolumes[i].getName()] = av->mCollisionVolumes[i].getName(); + } +} + void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm) { assert_main_thread(); @@ -1773,6 +1798,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable clearGLODGroup(); } + std::map<std::string, std::string> joint_alias_map; + getJointAliases(joint_alias_map); + mModelLoader = new LLDAELoader( filename, lod, @@ -1783,6 +1811,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable this, mJointTransformMap, mJointsFromNode, + joint_alias_map, + LLSkinningUtil::getMaxJointCount(), gSavedSettings.getU32("ImporterModelLimit"), gSavedSettings.getBOOL("ImporterPreprocessDAE")); @@ -1792,6 +1822,12 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable } else { + // For MAINT-6647, we have set force_disable_slm to true, + // which means this code path will never be taken. Trying to + // re-use SLM files has never worked properly; in particular, + // it tends to force the UI into strange checkbox options + // which cannot be altered. + //only try to load from slm if viewer is configured to do so and this is the //initial model load (not an LoD or physics shape) mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty(); @@ -1919,6 +1955,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) bool skin_weights = false; bool joint_positions = false; + bool lock_scale_if_joint_position = false; for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { //for each LoD @@ -1966,6 +2003,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { joint_positions = true; } + if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition) + { + lock_scale_if_joint_position = true; + } } } } @@ -1989,6 +2030,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) mViewOption["show_joint_positions"] = true; fmp->childSetValue("upload_joints", true); } + + if (lock_scale_if_joint_position) + { + fmp->enableViewOption("lock_scale_if_joint_position"); + mViewOption["lock_scale_if_joint_position"] = true; + fmp->childSetValue("lock_scale_if_joint_position", true); + } } //copy high lod to base scene for LoD generation @@ -3307,14 +3355,17 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLVector3 pos(vf.mPositions[i].getF32ptr()); const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); + llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this LLVector4 w(0,0,0,0); for (U32 i = 0; i < weight_list.size(); ++i) { - F32 wght = llmin(weight_list[i].mWeight, 0.999999f); + F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f); F32 joint = (F32) weight_list[i].mJointIdx; w.mV[i] = joint + wght; + llassert(w.mV[i]-(S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values + //should not cause floating point precision issues. } *(weights_strider++) = w; @@ -3367,19 +3418,6 @@ void LLModelPreview::update() } } -//----------------------------------------------------------------------------- -// getTranslationForJointOffset() -//----------------------------------------------------------------------------- -LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint ) -{ - LLMatrix4 jointTransform; - if ( mJointTransformMap.find( joint ) != mJointTransformMap.end() ) - { - jointTransform = mJointTransformMap[joint]; - return jointTransform.getTranslation(); - } - return LLVector3(0.0f,0.0f,0.0f); -} //----------------------------------------------------------------------------- // createPreviewAvatar //----------------------------------------------------------------------------- @@ -3509,6 +3547,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget ) pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() ); } + //----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- @@ -3627,7 +3666,17 @@ BOOL LLModelPreview::render() mFMP->childSetValue("upload_joints", false); upload_joints = false; } - + + if (upload_skin && upload_joints) + { + mFMP->childEnable("lock_scale_if_joint_position"); + } + else + { + mFMP->childDisable("lock_scale_if_joint_position"); + mFMP->childSetValue("lock_scale_if_joint_position", false); + } + //Only enable joint offsets if it passed the earlier critiquing if ( isRigValidForJointPositionUpload() ) { @@ -4002,20 +4051,6 @@ BOOL LLModelPreview::render() LLVector3::z_axis, // up target_pos); // point of interest - if (joint_positions) - { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - if (shader) - { - gDebugProgram.bind(); - } - getPreviewAvatar()->renderCollisionVolumes(); - if (shader) - { - shader->bind(); - } - } - for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) { for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) @@ -4040,58 +4075,32 @@ BOOL LLModelPreview::render() //quick 'n dirty software vertex skinning //build matrix palette - - LLMatrix4 mat[64]; - for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) - { - LLJoint* joint = getPreviewAvatar()->getJoint(model->mSkinInfo.mJointNames[j]); - if (joint) - { - mat[j] = model->mSkinInfo.mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); - } - } + LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + const LLMeshSkinInfo *skin = &model->mSkinInfo; + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, + skin, getPreviewAvatar()); + LLMatrix4a bind_shape_matrix; + bind_shape_matrix.loadu(skin->mBindShapeMatrix); + U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { - LLMatrix4 final_mat; - final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f; - - LLVector4 wght; - S32 idx[4]; - - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j].mV[k]; - - idx[k] = (S32) floorf(w); - wght.mV[k] = w - floorf(w); - scale += wght.mV[k]; - } - - wght *= 1.f/scale; - - for (U32 k = 0; k < 4; k++) - { - F32* src = (F32*) mat[idx[k]].mMatrix; - F32* dst = (F32*) final_mat.mMatrix; - - F32 w = wght.mV[k]; - - for (U32 l = 0; l < 16; l++) - { - dst[l] += src[l]*w; - } - } + LLMatrix4a final_mat; + F32 *wptr = weight[j].mV; + LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints); //VECTORIZE THIS - LLVector3 v(face.mPositions[j].getF32ptr()); + LLVector4a& v = face.mPositions[j]; - v = v * model->mSkinInfo.mBindShapeMatrix; - v = v * final_mat; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); - position[j] = v; + position[j][0] = dst[0]; + position[j][1] = dst[1]; + position[j][2] = dst[2]; } llassert(model->mMaterialList.size() > i); @@ -4125,6 +4134,22 @@ BOOL LLModelPreview::render() } } } + + if (joint_positions) + { + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + if (shader) + { + gDebugProgram.bind(); + } + getPreviewAvatar()->renderCollisionVolumes(); + getPreviewAvatar()->renderBones(); + if (shader) + { + shader->bind(); + } + } + } } @@ -4245,11 +4270,17 @@ void LLFloaterModelPreview::onUpload(void* user_data) bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = mp->childGetValue("upload_joints").asBoolean(); + bool lock_scale_if_joint_position = mp->childGetValue("lock_scale_if_joint_position").asBoolean(); - mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); + if (gSavedSettings.getBOOL("MeshImportUseSLM")) + { + mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions, lock_scale_if_joint_position); + } gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl, + mp->childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, + mp->mUploadModelUrl, true, LLHandle<LLWholeModelFeeObserver>(), mp->getWholeModelUploadObserverHandle()); } @@ -4261,7 +4292,14 @@ void LLFloaterModelPreview::refresh() } //static -void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ) +void LLModelPreview::textureLoadedCallback( + BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* src_aux, + S32 discard_level, + BOOL final, + void* userdata ) { LLModelPreview* preview = (LLModelPreview*) userdata; preview->refresh(); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index a73ca502608fb89cd35384252229278c53a06b04..a7a5c1b33aac7a4caf63f9c55d17a55a71af4149 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -260,6 +260,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex virtual BOOL needsRender() { return mNeedsUpdate; } void setPreviewLOD(S32 lod); void clearModel(S32 lod); + void getJointAliases(JointMap& joint_map); void loadModel(std::string filename, S32 lod, bool force_disable_slm = false); void loadModelCallback(S32 lod); bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); } @@ -269,8 +270,8 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex void restoreNormals(); U32 calcResourceCost(); void rebuildUploadData(); - void saveUploadData(bool save_skinweights, bool save_joint_poisitions); - void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); + void saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); + void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); void clearIncompatible(S32 lod); void updateStatusMessages(); void updateLodControls(S32 lod); @@ -300,11 +301,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex void setLoadState( U32 state ) { mLoadState = state; } U32 getLoadState() { return mLoadState; } - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - LLVector3 getTranslationForJointOffset( std::string joint ); - static bool sIgnoreLoadedCallback; std::vector<S32> mLodsQuery; @@ -352,7 +349,6 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex bool mLoading; U32 mLoadState; bool mResetJoints; - bool mRigParityWithScene; bool mModelNoErrors; std::map<std::string, bool> mViewOption; @@ -410,7 +406,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex bool mLastJointUpdate; - JointSet mJointsFromNode; + JointNameSet mJointsFromNode; JointTransformMap mJointTransformMap; LLPointer<LLVOAvatar> mPreviewAvatar; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 75f5e87a2b96108fcd2033da43732c7b68518f05..100ee5ab72dd49cb3a64a5fb01dcd12276794586 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1253,7 +1253,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny"); bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE); - + // Avatar Mode // Enable Avatar Shaders LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); @@ -2004,7 +2004,7 @@ void LLFloaterPreference::onClickAutoReplace() void LLFloaterPreference::onClickSpellChecker() { - LLFloaterReg::showInstance("prefs_spellchecker"); + LLFloaterReg::showInstance("prefs_spellchecker"); } void LLFloaterPreference::onClickAdvanced() diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e42647739f3cdb1aef6d2d6ea389677b584eab0c..9dacae2c4eff711ccd89fa7d9ebfeb7a00b28bee 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1901,7 +1901,8 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 } LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + const std::string & upload_url, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) : LLThread("mesh upload"), @@ -1916,6 +1917,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mUploadTextures = upload_textures; mUploadSkin = upload_skin; mUploadJoints = upload_joints; + mLockScaleIfJointPosition = lock_scale_if_joint_position; mMutex = new LLMutex(NULL); mPendingUploads = 0; mFinished = false; @@ -2102,6 +2104,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) decomp, mUploadSkin, mUploadJoints, + mLockScaleIfJointPosition, FALSE, FALSE, data.mBaseModel->mSubmodelID); @@ -2260,6 +2263,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) decomp, mUploadSkin, mUploadJoints, + mLockScaleIfJointPosition, FALSE, FALSE, data.mBaseModel->mSubmodelID); @@ -3973,11 +3977,13 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + std::string upload_url, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) { - LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url, - do_upload, fee_observer, upload_observer); + LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, + upload_skin, upload_joints, lock_scale_if_joint_position, + upload_url, do_upload, fee_observer, upload_observer); mUploadWaitList.push_back(thread); } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index a7620425979617b06d53df68012baf1ad187d82c..30f042845ad137a6ddbb36eaad610422cb6d9354 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -400,6 +400,7 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler bool mUploadTextures; bool mUploadSkin; bool mUploadJoints; + bool mLockScaleIfJointPosition; volatile bool mDiscarded; LLHost mHost; @@ -407,7 +408,8 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler std::string mWholeModelUploadURL; LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload = true, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + const std::string & upload_url, bool do_upload = true, LLHandle<LLWholeModelFeeObserver> fee_observer = (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); ~LLMeshUploadThread(); @@ -510,8 +512,10 @@ class LLMeshRepository LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, - LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + std::string upload_url, bool do_upload = true, + LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), + LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); S32 getMeshSize(const LLUUID& mesh_id, S32 lod); diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 35ac0537a3d01758397f939b3d13eb509d471ad4..fb40af1302dcc79419052d8da6e2724a1e6b131d 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -37,6 +37,7 @@ #include "lllineeditor.h" #include "lluictrlfactory.h" #include "lluictrlfactory.h" +#include "lldatapacker.h" extern LLAgent gAgent; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf09f6f9785a0c086b9aaf3c56cda128011e54da --- /dev/null +++ b/indra/newview/llskinningutil.cpp @@ -0,0 +1,218 @@ +/** +* @file llskinningutil.cpp +* @brief Functions for mesh object skinning +* @author vir@lindenlab.com +* +* $LicenseInfo:firstyear=2015&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2015, 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$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llskinningutil.h" +#include "llvoavatar.h" +#include "llviewercontrol.h" +#include "llmeshrepository.h" + +// static +void LLSkinningUtil::initClass() +{ +} + +// static +U32 LLSkinningUtil::getMaxJointCount() +{ + U32 result = LL_MAX_JOINTS_PER_MESH_OBJECT; + return result; +} + +// static +U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin) +{ + return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size()); +} + +// static +void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) +{ + if (skin->mInvalidJointsScrubbed) + { + return; + } + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + // Fix invalid names to "mPelvis". Currently meshes with + // invalid names will be blocked on upload, so this is just + // needed for handling of any legacy bad data. + if (!avatar->getJoint(skin->mJointNames[j])) + { + LL_DEBUGS("Avatar") << "Mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL; + skin->mJointNames[j] = "mPelvis"; + } + } + skin->mInvalidJointsScrubbed = true; +} + +// static +void LLSkinningUtil::initSkinningMatrixPalette( + LLMatrix4* mat, + S32 count, + const LLMeshSkinInfo* skin, + LLVOAvatar *avatar) +{ + for (U32 j = 0; j < count; ++j) + { + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + else + { + joint = avatar->getJoint(skin->mJointNums[j]); + } + if (joint) + { +#define MAT_USE_SSE +#ifdef MAT_USE_SSE + LLMatrix4a bind, world, res; + bind.loadu(skin->mInvBindMatrix[j]); + world.loadu(joint->getWorldMatrix()); + matMul(bind,world,res); + memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float)); +#else + mat[j] = skin->mInvBindMatrix[j]; + mat[j] *= joint->getWorldMatrix(); +#endif + } + else + { + mat[j] = skin->mInvBindMatrix[j]; + // This shouldn't happen - in mesh upload, skinned + // rendering should be disabled unless all joints are + // valid. In other cases of skinned rendering, invalid + // joints should already have been removed during scrubInvalidJoints(). + LL_WARNS_ONCE("Avatar") << "Rigged to invalid joint name " << skin->mJointNames[j] << LL_ENDL; + } + } +} + +// static +void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD + const S32 max_joints = skin->mJointNames.size(); + for (U32 j=0; j<num_vertices; j++) + { + F32 *w = weights[j].getF32ptr(); + + F32 wsum = 0.0; + for (U32 k=0; k<4; ++k) + { + S32 i = llfloor(w[k]); + llassert(i>=0); + llassert(i<max_joints); + wsum += w[k]-i; + } + llassert(wsum > 0.0f); + } +#endif +} + +void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ + const S32 max_joints = skin->mJointNames.size(); + for (U32 j=0; j<num_vertices; j++) + { + F32 *w = weights[j].getF32ptr(); + + for (U32 k=0; k<4; ++k) + { + S32 i = llfloor(w[k]); + F32 f = w[k]-i; + i = llclamp(i,0,max_joints-1); + w[k] = i + f; + } + } + checkSkinWeights(weights, num_vertices, skin); +} + +// static +void LLSkinningUtil::getPerVertexSkinMatrix( + F32* weights, + LLMatrix4a* mat, + bool handle_bad_scale, + LLMatrix4a& final_mat, + U32 max_joints) +{ + bool valid_weights = true; + final_mat.clear(); + + S32 idx[4]; + + LLVector4 wght; + + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weights[k]; + + // BENTO potential optimizations + // - Do clamping in unpackVolumeFaces() (once instead of every time) + // - int vs floor: if we know w is + // >= 0.0, we can use int instead of floorf; the latter + // allegedly has a lot of overhead due to ieeefp error + // checking which we should not need. + idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)max_joints-1); + + wght[k] = w - floorf(w); + scale += wght[k]; + } + if (handle_bad_scale && scale <= 0.f) + { + wght = LLVector4(1.0f, 0.0f, 0.0f, 0.0f); + valid_weights = false; + } + else + { + // This is enforced in unpackVolumeFaces() + llassert(scale>0.f); + wght *= 1.f/scale; + } + + for (U32 k = 0; k < 4; k++) + { + F32 w = wght[k]; + + LLMatrix4a src; + src.setMul(mat[idx[k]], w); + + final_mat.add(src); + } + // SL-366 - with weight validation/cleanup code, it should no longer be + // possible to hit the bad scale case. + llassert(valid_weights); +} + diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h new file mode 100644 index 0000000000000000000000000000000000000000..135b25d4d21c5d280e6764c758d5b8f6cc5d28df --- /dev/null +++ b/indra/newview/llskinningutil.h @@ -0,0 +1,47 @@ +/** +* @file llskinningutil.h +* @brief Functions for mesh object skinning +* @author vir@lindenlab.com +* +* $LicenseInfo:firstyear=2015&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2015, 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 LLSKINNINGUTIL_H +#define LLSKINNINGUTIL_H + +class LLVOAvatar; +class LLMeshSkinInfo; +class LLMatrix4a; + +class LLSkinningUtil +{ +public: + static void initClass(); + static U32 getMaxJointCount(); + static U32 getMeshJointCount(const LLMeshSkinInfo *skin); + static void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); + static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); + static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); + static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); + static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); +}; + +#endif diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index b0eb4137a735634a160a7af5fb9cf1bbf9cf01bc..0fd36766b3c9c68943a619dd9dcf9d7006333973 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3213,6 +3213,11 @@ void renderAvatarCollisionVolumes(LLVOAvatar* avatar) avatar->renderCollisionVolumes(); } +void renderAvatarBones(LLVOAvatar* avatar) +{ + avatar->renderBones(); +} + void renderAgentTarget(LLVOAvatar* avatar) { // render these for self only (why, i don't know) @@ -3371,6 +3376,11 @@ class LLOctreeRenderNonOccluded : public OctreeTraveler renderAvatarCollisionVolumes(avatar); } + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS)) + { + renderAvatarBones(avatar); + } + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) { renderAgentTarget(avatar); @@ -3661,6 +3671,7 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | LLPipeline::RENDER_DEBUG_RAYCAST | LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | + LLPipeline::RENDER_DEBUG_AVATAR_JOINTS | LLPipeline::RENDER_DEBUG_AGENT_TARGET | //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4e81d78455ef6ddd400b6c1db32d82e617985eaf..dab25f144ba971fc2a135c6ae3d0fc29957cbf1d 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -28,6 +28,7 @@ #include "llappviewer.h" #include "llstartup.h" +#include "llcallstack.h" #if LL_WINDOWS # include <process.h> // _spawnl() @@ -194,6 +195,8 @@ #include "lltoolbarview.h" #include "llexperiencelog.h" +#include "llstacktrace.h" + #if LL_WINDOWS #include "lldxhardware.h" #endif @@ -1222,7 +1225,7 @@ bool idle_startup() LLPostProcess::initClass(); display_startup(); - LLAvatarAppearance::initClass(); + LLAvatarAppearance::initClass("avatar_lad.xml","avatar_skeleton.xml"); display_startup(); LLViewerObject::initVOClasses(); diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index fd950864aa9c9fb340b09b0ad3bb134dc91e7634..01d799dcd50d62415c521a23ab9532cf81ccfbf2 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -283,7 +283,7 @@ bool LLToolBarView::loadToolbars(bool force_default) } BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.left_toolbar.commands) { - if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_LEFT])) + if (!addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_LEFT])) { LL_WARNS() << "Error adding command '" << command_params.name() << "' to left toolbar." << LL_ENDL; } @@ -298,7 +298,7 @@ bool LLToolBarView::loadToolbars(bool force_default) } BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.right_toolbar.commands) { - if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_RIGHT])) + if (!addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_RIGHT])) { LL_WARNS() << "Error adding command '" << command_params.name() << "' to right toolbar." << LL_ENDL; } @@ -313,7 +313,7 @@ bool LLToolBarView::loadToolbars(bool force_default) } BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.bottom_toolbar.commands) { - if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM])) + if (!addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM])) { LL_WARNS() << "Error adding command '" << command_params.name() << "' to bottom toolbar." << LL_ENDL; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 16f40fb747393d55ff6f6c0f177040f065062470..db7184965958c8ef0978d0a9d44f3236357d4855 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -67,6 +67,7 @@ #include "llvowlsky.h" #include "llrender.h" #include "llnavigationbar.h" +#include "llnotificationsutil.h" #include "llfloatertools.h" #include "llpaneloutfitsinventory.h" #include "llpanellogin.h" @@ -119,6 +120,13 @@ static bool handleTerrainDetailChanged(const LLSD& newvalue) } +static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) +{ + std::string new_string = newvalue.asString(); + LLJoint::setDebugJointNames(new_string); + return true; +} + static bool handleSetShaderChanged(const LLSD& newvalue) { // changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache @@ -741,6 +749,7 @@ void settings_setup_listeners() gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); + gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2)); } #if TEST_CACHED_CONTROL diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index e46299f9d2d54ae2cf90c2aff73944100d9ceaa6..b7bd131246a4ec3e647e229c3c494d6e8417c6ab 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -48,14 +48,13 @@ LLViewerJoint::LLViewerJoint() : LLAvatarJoint() { } -LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : - LLAvatarJoint(name, parent) -{ } - LLViewerJoint::LLViewerJoint(S32 joint_num) : LLAvatarJoint(joint_num) { } +LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : + LLAvatarJoint(name, parent) +{ } //----------------------------------------------------------------------------- // ~LLViewerJoint() diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index fd262b6e804793cfdc602545bd83dbd668ff2cd9..abe11bbf5c47a14dccfcea7c5ff0283539417b5b 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -44,7 +44,8 @@ class LLViewerJoint : { public: LLViewerJoint(); - LLViewerJoint(S32 joint_num); + LLViewerJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* LLViewerJoint(const std::string &name, LLJoint *parent = NULL); virtual ~LLViewerJoint(); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 888decd3bedebbed0717c70bec84bb8723814eb8..66e392ac424075f3ac3e3cb3d89705333073fef5 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -352,6 +352,7 @@ void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible) void LLViewerJointAttachment::setOriginalPosition(LLVector3& position) { mOriginalPos = position; + // SL-315 setPosition(position); } diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index bf7cf08c6364221e94b1f31ae5db841a2ee0e2d5..43a81ada4952ce35fb83e8fb4f757ee7a47fba33 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -203,7 +203,7 @@ void LLViewerJointMesh::uploadJointMatrices() // DrawElementsBLEND and utility code //-------------------------------------------------------------------- -// compate_int is used by the qsort function to sort the index array +// compare_int is used by the qsort function to sort the index array int compare_int(const void *a, const void *b) { if (*(U32*)a < *(U32*)b) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 39059fc01eab0e768bef2fa9fdc85de5d2bbada4..72579d4d7a429cac24f462ce676e190c6f4e0168 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -187,10 +187,10 @@ LLMenuGL* gDetachSubMenu = NULL; LLMenuGL* gTakeOffClothes = NULL; LLContextMenu* gAttachScreenPieMenu = NULL; LLContextMenu* gAttachPieMenu = NULL; -LLContextMenu* gAttachBodyPartPieMenus[8]; +LLContextMenu* gAttachBodyPartPieMenus[9]; LLContextMenu* gDetachPieMenu = NULL; LLContextMenu* gDetachScreenPieMenu = NULL; -LLContextMenu* gDetachBodyPartPieMenus[8]; +LLContextMenu* gDetachBodyPartPieMenus[9]; // // Local prototypes @@ -6000,6 +6000,31 @@ class LLAvatarToggleMyProfile : public view_listener_t } }; +class LLAvatarResetSkeleton: public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + avatar->resetSkeleton(false); + } + return true; + } +}; + +class LLAvatarResetSkeletonAndAnimations : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + if (avatar) + { + avatar->resetSkeleton(true); + } + return true; + } +}; class LLAvatarAddContact : public view_listener_t { @@ -8991,6 +9016,8 @@ void initialize_menus() enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall)); view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse"); view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile"); + view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton"); + view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations"); enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible)); commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL"))); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index a553bb79a26503aad497451dee3021bb24109074..7abb0c8e748f9c833d9e9b769badb963e9db4a1f 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -189,8 +189,8 @@ extern LLContextMenu* gAttachScreenPieMenu; extern LLContextMenu* gDetachScreenPieMenu; extern LLContextMenu* gAttachPieMenu; extern LLContextMenu* gDetachPieMenu; -extern LLContextMenu* gAttachBodyPartPieMenus[8]; -extern LLContextMenu* gDetachBodyPartPieMenus[8]; +extern LLContextMenu* gAttachBodyPartPieMenus[9]; +extern LLContextMenu* gDetachBodyPartPieMenus[9]; extern LLMenuItemCallGL* gMutePieMenu; extern LLMenuItemCallGL* gMuteObjectPieMenu; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 7964bf18481865439928cfc59b8f3b4b98c16862..4da26404e5efc1b0d768c80f4b780697296acddc 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -371,7 +371,7 @@ void LLViewerObject::markDead() if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) { // This case is needed for indirectly attached mesh objects. - av->resetJointPositionsOnDetach(mesh_id); + av->resetJointsOnDetach(mesh_id); } // Mark itself as dead diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index dafe2cafec02676632892c7871201e6be3f52432..3e0cec0f0999e7fb19b05ae4141f28bd03789070 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -27,6 +27,8 @@ #include "llviewerprecompiledheaders.h" +#include <boost/lexical_cast.hpp> + #include "llfeaturemanager.h" #include "llviewershadermgr.h" @@ -41,6 +43,8 @@ #include "llsky.h" #include "llvosky.h" #include "llrender.h" +#include "lljoint.h" +#include "llskinningutil.h" #ifdef LL_RELEASE_FOR_DOWNLOAD #define UNIFORM_ERRS LL_WARNS_ONCE("Shader") @@ -871,7 +875,9 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); boost::unordered_map<std::string, std::string> attribs; - + attribs["MAX_JOINTS_PER_MESH_OBJECT"] = + boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount()); + // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. for (U32 i = 0; i < shaders.size(); i++) { diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 88eb13e7cdfdcef607620d1cf6c84466e9f16339..ae9ce37a28cfd6c5307459d1999d7bcacb227d49 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -70,7 +70,7 @@ class LLOverrideBakedTextureUpdate }; // Private local functions -static std::string asset_id_to_filename(const LLUUID &asset_id); +static std::string asset_id_to_filename(const LLUUID &asset_id, const ELLPath dir_spec); LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) : LLWearable(), @@ -513,7 +513,7 @@ void LLViewerWearable::saveNewAsset() const // LL_INFOS() << "LLViewerWearable::saveNewAsset() type: " << getTypeName() << LL_ENDL; //LL_INFOS() << *this << LL_ENDL; - const std::string filename = asset_id_to_filename(mAssetID); + const std::string filename = asset_id_to_filename(mAssetID, LL_PATH_CACHE); if(! exportFile(filename)) { std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str()); @@ -525,6 +525,12 @@ void LLViewerWearable::saveNewAsset() const return; } + if (gSavedSettings.getBOOL("LogWearableAssetSave")) + { + const std::string log_filename = asset_id_to_filename(mAssetID, LL_PATH_LOGS); + exportFile(log_filename); + } + // save it out to database if( gAssetStorage ) { @@ -573,7 +579,7 @@ void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* } // Delete temp file - const std::string src_filename = asset_id_to_filename(new_asset_id); + const std::string src_filename = asset_id_to_filename(new_asset_id, LL_PATH_CACHE); LLFile::remove(src_filename); // delete the context data @@ -610,10 +616,10 @@ std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w) return s; } -std::string asset_id_to_filename(const LLUUID &asset_id) +std::string asset_id_to_filename(const LLUUID &asset_id, const ELLPath dir_spec) { std::string asset_id_string; asset_id.toString(asset_id_string); - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl"; + std::string filename = gDirUtilp->getExpandedFilename(dir_spec,asset_id_string) + ".wbl"; return filename; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1425b3d42ef4991316f4c157178528442655c3c9..96a1beffbc326354a47cf26765220df5b853087c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -106,6 +106,8 @@ #include "llsdutil.h" #include "llscenemonitor.h" #include "llsdserialize.h" +#include "llcallstack.h" +#include "llrendersphere.h" extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; @@ -215,26 +217,8 @@ struct LLTextureMaskData ** **/ -//------------------------------------------------------------------------ -// LLVOAvatarBoneInfo -// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton. -//------------------------------------------------------------------------ -struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo> -{ - LLVOAvatarCollisionVolumeInfo() - : name("name"), - pos("pos"), - rot("rot"), - scale("scale") - {} - Mandatory<std::string> name; - Mandatory<LLVector3> pos, - rot, - scale; -}; - -struct LLAppearanceMessageContents +struct LLAppearanceMessageContents: public LLRefCount { LLAppearanceMessageContents(): mAppearanceVersion(-1), @@ -254,49 +238,6 @@ struct LLAppearanceMessageContents bool mHoverOffsetWasSet; }; -struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint> - { - Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone; - Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume; - - LLVOAvatarChildJoint() - : bone("bone"), - collision_volume("collision_volume") - {} -}; - - - -struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo> -{ - LLVOAvatarBoneInfo() - : pivot("pivot") - {} - - Mandatory<LLVector3> pivot; - Multiple<LLVOAvatarChildJoint> children; -}; - -//------------------------------------------------------------------------ -// LLVOAvatarSkeletonInfo -// Overall avatar skeleton -//------------------------------------------------------------------------ -struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo> -{ - LLVOAvatarSkeletonInfo() - : skeleton_root(""), - num_bones("num_bones"), - num_collision_volumes("num_collision_volumes"), - version("version") - {} - - Mandatory<std::string> version; - Mandatory<S32> num_bones, - num_collision_volumes; - Mandatory<LLVOAvatarChildJoint> skeleton_root; -}; - - //----------------------------------------------------------------------------- // class LLBodyNoiseMotion @@ -1112,7 +1053,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) { if (LLViewerTexLayerSet::sHasCaches) { - LL_DEBUGS() << "Deleting layer set caches" << LL_ENDL; for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { @@ -1143,6 +1083,9 @@ void LLVOAvatar::initClass() gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix"); gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target"); gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust"); + + // Where should this be set initially? + LLJoint::setDebugJointNames(gSavedSettings.getString("DebugAvatarJoints")); } @@ -1396,18 +1339,78 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) newMax.add(buffer); } +void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos, F32 sphere_scale, const LLVector3& occ_color, const LLVector3& visible_color) +{ + // Unoccluded bone portions + LLGLDepthTest normal_depth(GL_TRUE); + + // Draw line segment for unoccluded joint + gGL.diffuseColor3f(visible_color[0], visible_color[1], visible_color[2]); + + gGL.begin(LLRender::LINES); + gGL.vertex3fv(begin_pos.mV); + gGL.vertex3fv(end_pos.mV); + gGL.end(); + + + // Draw sphere representing joint pos + gGL.pushMatrix(); + gGL.scalef(sphere_scale, sphere_scale, sphere_scale); + gSphere.renderGGL(); + gGL.popMatrix(); + + LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); + + // Occluded bone portions + gGL.diffuseColor3f(occ_color[0], occ_color[1], occ_color[2]); + + gGL.begin(LLRender::LINES); + gGL.vertex3fv(begin_pos.mV); + gGL.vertex3fv(end_pos.mV); + gGL.end(); + + // Draw sphere representing joint pos + gGL.pushMatrix(); + gGL.scalef(sphere_scale, sphere_scale, sphere_scale); + gSphere.renderGGL(); + gGL.popMatrix(); +} + //----------------------------------------------------------------------------- // renderCollisionVolumes() //----------------------------------------------------------------------------- void LLVOAvatar::renderCollisionVolumes() { std::ostringstream ostr; + for (S32 i = 0; i < mNumCollisionVolumes; i++) { - mCollisionVolumes[i].renderCollision(); ostr << mCollisionVolumes[i].getName() << ", "; - } + LLAvatarJointCollisionVolume& collision_volume = mCollisionVolumes[i]; + + collision_volume.updateWorldMatrix(); + + gGL.pushMatrix(); + gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] ); + + LLVector3 begin_pos(0,0,0); + LLVector3 end_pos(collision_volume.getEnd()); + static F32 sphere_scale = 1.0f; + static F32 center_dot_scale = 0.05f; + + static LLVector3 CV_COLOR_OCCLUDED(0.0f, 0.0f, 1.0f); + static LLVector3 CV_COLOR_VISIBLE(0.5f, 0.5f, 1.0f); + static LLVector3 DOT_COLOR_OCCLUDED(1.0f, 1.0f, 1.0f); + static LLVector3 DOT_COLOR_VISIBLE(1.0f, 1.0f, 1.0f); + + render_sphere_and_line(begin_pos, end_pos, sphere_scale, CV_COLOR_OCCLUDED, CV_COLOR_VISIBLE); + render_sphere_and_line(begin_pos, end_pos, center_dot_scale, DOT_COLOR_OCCLUDED, DOT_COLOR_VISIBLE); + + gGL.popMatrix(); + } + + if (mNameText.notNull()) { LLVector4a unused; @@ -1419,6 +1422,72 @@ void LLVOAvatar::renderCollisionVolumes() addDebugText(ostr.str()); } +void LLVOAvatar::renderBones() +{ + LLGLEnable blend(GL_BLEND); + + avatar_joint_list_t::iterator iter = mSkeleton.begin(); + avatar_joint_list_t::iterator end = mSkeleton.end(); + + // For bones with position overrides defined + static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f); + static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // For bones which are rigged to by at least one attachment + static LLVector3 RIGGED_COLOR_OCCLUDED(0.0f, 1.0f, 1.0f); + static LLVector3 RIGGED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // For bones not otherwise colored + static LLVector3 OTHER_COLOR_OCCLUDED(0.0f, 1.0f, 0.0f); + static LLVector3 OTHER_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + + static F32 SPHERE_SCALEF = 0.001f; + + for (; iter != end; ++iter) + { + LLJoint* jointp = *iter; + if (!jointp) + { + continue; + } + + jointp->updateWorldMatrix(); + + LLVector3 occ_color, visible_color; + + LLVector3 pos; + LLUUID mesh_id; + if (jointp->hasAttachmentPosOverride(pos,mesh_id)) + { + occ_color = OVERRIDE_COLOR_OCCLUDED; + visible_color = OVERRIDE_COLOR_VISIBLE; + } + else + { + if (jointIsRiggedTo(jointp->getName())) + { + occ_color = RIGGED_COLOR_OCCLUDED; + visible_color = RIGGED_COLOR_VISIBLE; + } + else + { + occ_color = OTHER_COLOR_OCCLUDED; + visible_color = OTHER_COLOR_VISIBLE; + } + } + LLVector3 begin_pos(0,0,0); + LLVector3 end_pos(jointp->getEnd()); + + F32 sphere_scale = SPHERE_SCALEF; + + gGL.pushMatrix(); + gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); + + render_sphere_and_line(begin_pos, end_pos, sphere_scale, occ_color, visible_color); + + gGL.popMatrix(); + } +} + + void LLVOAvatar::renderJoints() { std::ostringstream ostr; @@ -1526,7 +1595,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& for (S32 i = 0; i < mNumCollisionVolumes; ++i) { mCollisionVolumes[i].updateWorldMatrix(); - + glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix); glh::matrix4f inverse = mat.inverse(); glh::matrix4f norm_mat = inverse.transpose(); @@ -1735,6 +1804,133 @@ void LLVOAvatar::buildCharacter() mMeshValid = TRUE; } +//----------------------------------------------------------------------------- +// resetVisualParams() +//----------------------------------------------------------------------------- +void LLVOAvatar::resetVisualParams() +{ + // Skeletal params + { + LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; + for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); + iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); + ++iter) + { + LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter; + LLPolySkeletalDistortion *param = dynamic_cast<LLPolySkeletalDistortion*>(getVisualParam(info->getID())); + *param = LLPolySkeletalDistortion(this); + llassert(param); + if (!param->setInfo(info)) + { + llassert(false); + } + } + } + + // Driver parameters + for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); + iter != sAvatarXmlInfo->mDriverInfoList.end(); + ++iter) + { + LLDriverParamInfo *info = *iter; + LLDriverParam *param = dynamic_cast<LLDriverParam*>(getVisualParam(info->getID())); + LLDriverParam::entry_list_t driven_list = param->getDrivenList(); + *param = LLDriverParam(this); + llassert(param); + if (!param->setInfo(info)) + { + llassert(false); + } + param->setDrivenList(driven_list); + } +} + +//----------------------------------------------------------------------------- +// resetSkeleton() +//----------------------------------------------------------------------------- +void LLVOAvatar::resetSkeleton(bool reset_animations) +{ + LL_DEBUGS("Avatar") << avString() << " reset starts" << LL_ENDL; + if (!mLastProcessedAppearance) + { + LL_WARNS() << "Can't reset avatar; no appearance message has been received yet." << LL_ENDL; + return; + } + + // Save mPelvis state + //LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); + //LLQuaternion pelvis_rot = getJoint("mPelvis")->getRotation(); + + // Clear all attachment pos and scale overrides + clearAttachmentOverrides(); + + // Note that we call buildSkeleton twice in this function. The first time is + // just to get the right scale for the collision volumes, because + // this will be used in setting the mJointScales for the + // LLPolySkeletalDistortions of which the CVs are children. + if( !buildSkeleton(sAvatarSkeletonInfo) ) + { + LL_ERRS() << "Error resetting skeleton" << LL_ENDL; + } + + // Reset some params to default state, without propagating changes downstream. + resetVisualParams(); + + // Now we have to reset the skeleton again, because its state + // got clobbered by the resetVisualParams() calls + // above. + if( !buildSkeleton(sAvatarSkeletonInfo) ) + { + LL_ERRS() << "Error resetting skeleton" << LL_ENDL; + } + + // Reset attachment points (buildSkeleton only does bones and CVs) + bool ignore_hud_joints = true; + initAttachmentPoints(ignore_hud_joints); + + // Fix up collision volumes + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + LLPolyMorphTarget *poly_morph = dynamic_cast<LLPolyMorphTarget*>(param); + if (poly_morph) + { + // This is a kludgy way to correct for the fact that the + // collision volumes have been reset out from under the + // poly morph sliders. + F32 delta_weight = poly_morph->getLastWeight() - poly_morph->getDefaultWeight(); + poly_morph->applyVolumeChanges(delta_weight); + } + } + + // Reset tweakable params to preserved state + bool slam_params = true; + applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); + updateVisualParams(); + + // Restore attachment pos overrides + rebuildAttachmentOverrides(); + + // Animations + if (reset_animations) + { + if (isSelf()) + { + // This is equivalent to "Stop Animating Me". Will reset + // all animations and propagate the changes to other + // viewers. + gAgent.stopCurrentAnimations(); + } + else + { + // Local viewer-side reset for non-self avatars. + resetAnimations(); + } + } + + LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL; +} //----------------------------------------------------------------------------- // releaseMeshData() @@ -1746,8 +1942,6 @@ void LLVOAvatar::releaseMeshData() return; } - LL_DEBUGS() << "Releasing mesh data" << LL_ENDL; - // cleanup mesh data for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); iter != mMeshLOD.end(); @@ -1957,17 +2151,12 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, // Do base class updates... U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - //LLTEContents tec; - //S32 te_retval = parseTEMessage(mesgsys, _PREHASH_ObjectData, block_num, tec); - - LL_DEBUGS("Avatar") << avString() << update_type << LL_ENDL; - // Print out arrival information once we have name of avatar. - if (has_name && getNVPair("FirstName")) - { - mDebugExistenceTimer.reset(); - debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); - } + if (has_name && getNVPair("FirstName")) + { + mDebugExistenceTimer.reset(); + debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); + } if(retval & LLViewerObject::INVALID_UPDATE) { @@ -2075,6 +2264,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) return; } + LLScopedContextString str("avatar_idle_update " + getFullname()); + checkTextureLoading() ; // force immediate pixel area update on avatars using last frames data (before drawable or camera updates) @@ -3079,6 +3270,7 @@ void LLVOAvatar::idleUpdateBelowWater() void LLVOAvatar::slamPosition() { gAgent.setPositionAgent(getPositionAgent()); + // SL-315 mRoot->setWorldPosition(getPositionAgent()); // teleport setChanged(TRANSLATED); if (mDrawable.notNull()) @@ -3176,23 +3368,31 @@ void LLVOAvatar::updateDebugText() { debug_line += llformat(" - cof rcv:%d", last_received_cof_version); } - debug_line += llformat(" bsz-z: %f avofs-z: %f", mBodySize[2], mAvatarOffset[2]); + debug_line += llformat(" bsz-z: %.3f", mBodySize[2]); + if (mAvatarOffset[2] != 0.0f) + { + debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]); + } bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled(); debug_line += hover_enabled ? " H" : " h"; const LLVector3& hover_offset = getHoverOffset(); if (hover_offset[2] != 0.0) { - debug_line += llformat(" hov_z: %f", hover_offset[2]); + debug_line += llformat(" hov_z: %.3f", hover_offset[2]); debug_line += llformat(" %s", (mIsSitting ? "S" : "T")); debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); } - F32 elapsed = mLastAppearanceMessageTimer.getElapsedTimeF32(); - static const char *elapsed_chars = "Xx*..."; - U32 bucket = U32(elapsed*2); - if (bucket < strlen(elapsed_chars)) - { - debug_line += llformat(" %c", elapsed_chars[bucket]); - } + LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); + LLVector3 normal; + LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; + resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); + F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); + debug_line += llformat(" relev %.3f", rightElev); + + LLVector3 root_pos = mRoot->getPosition(); + LLVector3 pelvis_pos = mPelvisp->getPosition(); + debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); + addDebugText(debug_line); } if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) @@ -3377,6 +3577,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mTimeLast = animation_time; // put the pelvis at slaved position/mRotation + // SL-315 mRoot->setWorldPosition( getPositionAgent() ); // first frame mRoot->setWorldRotation( getRotation() ); } @@ -3417,6 +3618,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } mInAir = in_air; + // SL-402: with the ability to animate the position of joints + // that affect the body size calculation, computed body size + // can get stale much more easily. Simplest fix is to update + // it frequently. + // SL-427: this appears to be too frequent, moving to only do on animation state change. + //computeBodySize(); + // correct for the fact that the pelvis is not necessarily the center // of the agent's physical representation root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot; @@ -3431,6 +3639,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) if (newPosition != mRoot->getXform()->getWorldPosition()) { mRoot->touch(); + // SL-315 mRoot->setWorldPosition( newPosition ); // regular update } @@ -3594,6 +3803,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { LLVector3 pos = mDrawable->getPosition(); pos += getHoverOffset() * mDrawable->getRotation(); + // SL-315 mRoot->setPosition(pos); mRoot->setRotation(mDrawable->getRotation()); } @@ -3624,6 +3834,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) LLVector3 pos = mRoot->getWorldPosition(); pos.mV[VZ] += off_z; mRoot->touch(); + // SL-315 mRoot->setWorldPosition(pos); } } @@ -3739,10 +3950,78 @@ void LLVOAvatar::updateHeadOffset() mHeadOffset = lerp(midEyePt, mHeadOffset, u); } } + +void LLVOAvatar::debugBodySize() const +{ + LLVector3 pelvis_scale = mPelvisp->getScale(); + + // some of the joints have not been cached + LLVector3 skull = mSkullp->getPosition(); + LL_DEBUGS("Avatar") << "skull pos " << skull << LL_ENDL; + //LLVector3 skull_scale = mSkullp->getScale(); + + LLVector3 neck = mNeckp->getPosition(); + LLVector3 neck_scale = mNeckp->getScale(); + LL_DEBUGS("Avatar") << "neck pos " << neck << " neck_scale " << neck_scale << LL_ENDL; + + LLVector3 chest = mChestp->getPosition(); + LLVector3 chest_scale = mChestp->getScale(); + LL_DEBUGS("Avatar") << "chest pos " << chest << " chest_scale " << chest_scale << LL_ENDL; + + // the rest of the joints have been cached + LLVector3 head = mHeadp->getPosition(); + LLVector3 head_scale = mHeadp->getScale(); + LL_DEBUGS("Avatar") << "head pos " << head << " head_scale " << head_scale << LL_ENDL; + + LLVector3 torso = mTorsop->getPosition(); + LLVector3 torso_scale = mTorsop->getScale(); + LL_DEBUGS("Avatar") << "torso pos " << torso << " torso_scale " << torso_scale << LL_ENDL; + + LLVector3 hip = mHipLeftp->getPosition(); + LLVector3 hip_scale = mHipLeftp->getScale(); + LL_DEBUGS("Avatar") << "hip pos " << hip << " hip_scale " << hip_scale << LL_ENDL; + + LLVector3 knee = mKneeLeftp->getPosition(); + LLVector3 knee_scale = mKneeLeftp->getScale(); + LL_DEBUGS("Avatar") << "knee pos " << knee << " knee_scale " << knee_scale << LL_ENDL; + + LLVector3 ankle = mAnkleLeftp->getPosition(); + LLVector3 ankle_scale = mAnkleLeftp->getScale(); + LL_DEBUGS("Avatar") << "ankle pos " << ankle << " ankle_scale " << ankle_scale << LL_ENDL; + + LLVector3 foot = mFootLeftp->getPosition(); + LL_DEBUGS("Avatar") << "foot pos " << foot << LL_ENDL; + + F32 new_offset = (const_cast<LLVOAvatar*>(this))->getVisualParamWeight(AVATAR_HOVER); + LL_DEBUGS("Avatar") << "new_offset " << new_offset << LL_ENDL; + + F32 new_pelvis_to_foot = 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]; + LL_DEBUGS("Avatar") << "new_pelvis_to_foot " << new_pelvis_to_foot << LL_ENDL; + + LLVector3 new_body_size; + new_body_size.mV[VZ] = new_pelvis_to_foot + + // 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; + + LL_DEBUGS("Avatar") << "new_body_size " << new_body_size << LL_ENDL; +} + //------------------------------------------------------------------------ // postPelvisSetRecalc //------------------------------------------------------------------------ -void LLVOAvatar::postPelvisSetRecalc( void ) +void LLVOAvatar::postPelvisSetRecalc() { mRoot->updateWorldMatrixChildren(); computeBodySize(); @@ -4832,6 +5111,12 @@ void LLVOAvatar::processAnimationStateChanges() //----------------------------------------------------------------------------- BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start ) { + // SL-402, SL-427 - we need to update body size often enough to + // keep appearances in sync, but not so often that animations + // cause constant jiggling of the body or camera. Possible + // compromise is to do it on animation changes: + computeBodySize(); + BOOL result = FALSE; if ( start ) // start animation @@ -5056,18 +5341,52 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { //search for joint and cache found joint in lookup table + { //search for joint and cache found joint in lookup table jointp = mRoot->findJoint(name); mJointMap[name] = jointp; } else - { //return cached pointer + { //return cached pointer jointp = iter->second; } +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot") + { + llassert(getJoint(jointp->getJointNum())==jointp); + } +#endif return jointp; } +LLJoint *LLVOAvatar::getJoint( S32 joint_num ) +{ + LLJoint *pJoint = NULL; + S32 collision_start = mNumBones; + S32 attachment_start = mNumBones + mNumCollisionVolumes; + if (joint_num>=attachment_start) + { + // Attachment IDs start at 1 + S32 attachment_id = joint_num - attachment_start + 1; + attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); + if (iter != mAttachmentPoints.end()) + { + pJoint = iter->second; + } + } + else if (joint_num>=collision_start) + { + S32 collision_id = joint_num-collision_start; + pJoint = &mCollisionVolumes[collision_id]; + } + else if (joint_num>=0) + { + pJoint = mSkeleton[joint_num]; + } + llassert(!pJoint || pJoint->getJointNum() == joint_num); + return pJoint; +} + //----------------------------------------------------------------------------- // getRiggedMeshID // @@ -5098,37 +5417,121 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) return false; } -void LLVOAvatar::clearAttachmentPosOverrides() +bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) { - //Subsequent joints are relative to pelvis - avatar_joint_list_t::iterator iter = mSkeleton.begin(); - avatar_joint_list_t::iterator end = mSkeleton.end(); + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && jointIsRiggedTo(joint_name, attached_object)) + { + return true; + } + } + } + return false; +} - for (; iter != end; ++iter) +bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo) +{ + // Process all children + LLViewerObject::const_child_list_t& children = vo->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) { - LLJoint* pJoint = (*iter); - pJoint->clearAttachmentPosOverrides(); + LLViewerObject *childp = *it; + if (jointIsRiggedTo(joint_name,childp)) + { + return true; + } } + + const LLVOVolume *vobj = dynamic_cast<const LLVOVolume*>(vo); + if (!vobj) + { + return false; + } + + LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); + + if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) + { + if (std::find(pSkinData->mJointNames.begin(), pSkinData->mJointNames.end(), joint_name) != + pSkinData->mJointNames.end()) + { + return true; + } + } + + return false; } +void LLVOAvatar::clearAttachmentOverrides() +{ + LLScopedContextString str("clearAttachmentOverrides " + getFullname()); + + for (S32 i=0; i<LL_CHARACTER_MAX_ANIMATED_JOINTS; i++) + { + LLJoint *pJoint = getJoint(i); + if (pJoint) + { + pJoint->clearAttachmentPosOverrides(); + pJoint->clearAttachmentScaleOverrides(); + } + } +} + +//----------------------------------------------------------------------------- +// rebuildAttachmentOverrides +//----------------------------------------------------------------------------- +void LLVOAvatar::rebuildAttachmentOverrides() +{ + LLScopedContextString str("rebuildAttachmentOverrides " + getFullname()); + + // Attachment points + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment *attachment_pt = (*iter).second; + if (attachment_pt) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin(); + at_it != attachment_pt->mAttachedObjects.end(); ++at_it) + { + addAttachmentOverridesForObject(*at_it); + } + } + } +} //----------------------------------------------------------------------------- // addAttachmentPosOverridesForObject //----------------------------------------------------------------------------- -void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) +void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) { LLVOAvatar *av = vo->getAvatarAncestor(); if (!av || (av != this)) { LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; + return; } - + + LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname()); + // Process all children LLViewerObject::const_child_list_t& children = vo->getChildren(); for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); it != children.end(); ++it) { LLViewerObject *childp = *it; - addAttachmentPosOverridesForObject(childp); + addAttachmentOverridesForObject(childp); } LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo); @@ -5149,9 +5552,13 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) { const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) + const int jointCnt = pSkinData->mJointNames.size(); + if ((bindCnt > 0) && (bindCnt != jointCnt)) + { + LL_WARNS_ONCE() << "invalid mesh, bindCnt " << bindCnt << "!= jointCnt " << jointCnt << ", joint overrides will be ignored." << LL_ENDL; + } + if ((bindCnt > 0) && (bindCnt == jointCnt)) { - const int jointCnt = pSkinData->mJointNames.size(); const F32 pelvisZOffset = pSkinData->mPelvisOffset; const LLUUID& mesh_id = pSkinData->mMeshID; bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; @@ -5161,24 +5568,43 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) { std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); LLJoint* pJoint = getJoint( lookingForJoint ); - if ( pJoint && pJoint->getId() != currentId ) + if (pJoint) { - pJoint->setId( currentId ); const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); - //Set the joint position - pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() ); - - //If joint is a pelvis then handle old/new pelvis to foot values - if ( lookingForJoint == "mPelvis" ) - { - pelvisGotSet = true; - } + if (pJoint->aboveJointPosThreshold(jointPos)) + { + bool override_changed; + pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); + + if (override_changed) + { + //If joint is a pelvis then handle old/new pelvis to foot values + if ( lookingForJoint == "mPelvis" ) + { + pelvisGotSet = true; + } + } + if (pSkinData->mLockScaleIfJointPosition) + { + // Note that unlike positions, there's no threshold check here, + // just a lock at the default value. + pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString()); + } + } } } if (pelvisZOffset != 0.0F) { + F32 pelvis_fixup_before; + bool has_fixup_before = hasPelvisFixup(pelvis_fixup_before); addPelvisFixup( pelvisZOffset, mesh_id ); - pelvisGotSet = true; + F32 pelvis_fixup_after; + hasPelvisFixup(pelvis_fixup_after); // Don't have to check bool here because we just added it... + if (!has_fixup_before || (pelvis_fixup_before != pelvis_fixup_after)) + { + pelvisGotSet = true; + } + } } } @@ -5192,9 +5618,122 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) } //----------------------------------------------------------------------------- -// resetJointPositionsOnDetach +// getAttachmentOverrideNames +//----------------------------------------------------------------------------- +void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& pos_names, std::set<std::string>& scale_names) const +{ + LLVector3 pos; + LLVector3 scale; + LLUUID mesh_id; + + // Bones + for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); + iter != mSkeleton.end(); ++iter) + { + const LLJoint* pJoint = (*iter); + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) + { + pos_names.insert(pJoint->getName()); + } + if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) + { + scale_names.insert(pJoint->getName()); + } + } + + // Attachment points + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; + if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id)) + { + pos_names.insert(attachment_pt->getName()); + } + // Attachment points don't have scales. + } + +} + +//----------------------------------------------------------------------------- +// showAttachmentOverrides //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo) +void LLVOAvatar::showAttachmentOverrides(bool verbose) const +{ + std::set<std::string> pos_names, scale_names; + getAttachmentOverrideNames(pos_names, scale_names); + if (pos_names.size()) + { + std::stringstream ss; + std::copy(pos_names.begin(), pos_names.end(), std::ostream_iterator<std::string>(ss, ",")); + LL_INFOS() << getFullname() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << getFullname() << " no attachment positions defined for any joints" << "\n" << LL_ENDL; + } + if (scale_names.size()) + { + std::stringstream ss; + std::copy(scale_names.begin(), scale_names.end(), std::ostream_iterator<std::string>(ss, ",")); + LL_INFOS() << getFullname() << " attachment scales defined for joints: " << ss.str() << "\n" << LL_ENDL; + } + else + { + LL_INFOS() << getFullname() << " no attachment scales defined for any joints" << "\n" << LL_ENDL; + } + + if (!verbose) + { + return; + } + + LLVector3 pos, scale; + LLUUID mesh_id; + S32 count = 0; + + // Bones + for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); + iter != mSkeleton.end(); ++iter) + { + const LLJoint* pJoint = (*iter); + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) + { + pJoint->showAttachmentPosOverrides(getFullname()); + count++; + } + if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) + { + pJoint->showAttachmentScaleOverrides(getFullname()); + count++; + } + } + + // Attachment points + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; + if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id)) + { + attachment_pt->showAttachmentPosOverrides(getFullname()); + count++; + } + } + + if (count) + { + LL_DEBUGS("Avatar") << avString() << " end of pos, scale overrides" << LL_ENDL; + LL_DEBUGS("Avatar") << "=================================" << LL_ENDL; + } +} + +//----------------------------------------------------------------------------- +// resetJointsOnDetach +//----------------------------------------------------------------------------- +void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo) { LLVOAvatar *av = vo->getAvatarAncestor(); if (!av || (av != this)) @@ -5208,21 +5747,21 @@ void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo) it != children.end(); ++it) { LLViewerObject *childp = *it; - resetJointPositionsOnDetach(childp); + resetJointsOnDetach(childp); } // Process self. LLUUID mesh_id; if (getRiggedMeshID(vo,mesh_id)) { - resetJointPositionsOnDetach(mesh_id); + resetJointsOnDetach(mesh_id); } } //----------------------------------------------------------------------------- -// resetJointPositionsOnDetach +// resetJointsOnDetach //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) +void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id) { //Subsequent joints are relative to pelvis avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5236,12 +5775,14 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) //Reset joints except for pelvis if ( pJoint ) { - pJoint->setId( LLUUID::null ); - pJoint->removeAttachmentPosOverride(mesh_id, avString()); + bool dummy; // unused + pJoint->removeAttachmentPosOverride(mesh_id, avString(),dummy); + pJoint->removeAttachmentScaleOverride(mesh_id, avString()); } if ( pJoint && pJoint == pJointPelvis) { removePelvisFixup( mesh_id ); + // SL-315 pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); } } @@ -5373,83 +5914,99 @@ BOOL LLVOAvatar::loadSkeletonNode () return FALSE; } - // ATTACHMENTS - { - LLAvatarXmlInfo::attachment_info_list_t::iterator iter; - for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); - iter != sAvatarXmlInfo->mAttachmentInfoList.end(); - ++iter) - { - LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter; - if (!isSelf() && info->mJointName == "mScreen") - { //don't process screen joint for other avatars - continue; - } + bool ignore_hud_joints = false; + initAttachmentPoints(ignore_hud_joints); - LLViewerJointAttachment* attachment = new LLViewerJointAttachment(); + return TRUE; +} - attachment->setName(info->mName); - LLJoint *parentJoint = getJoint(info->mJointName); - if (!parentJoint) - { - LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL; - delete attachment; - continue; - } +//----------------------------------------------------------------------------- +// initAttachmentPoints(): creates attachment points if needed, sets state based on avatar_lad.xml. +//----------------------------------------------------------------------------- +void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) +{ + LLAvatarXmlInfo::attachment_info_list_t::iterator iter; + for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); + iter != sAvatarXmlInfo->mAttachmentInfoList.end(); + ++iter) + { + LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter; + if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints)) + { + //don't process hud joint for other avatars, or when doing a skeleton reset. + continue; + } - if (info->mHasPosition) - { - attachment->setOriginalPosition(info->mPosition); - } - - if (info->mHasRotation) - { - LLQuaternion rotation; - rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD, - info->mRotationEuler.mV[VY] * DEG_TO_RAD, - info->mRotationEuler.mV[VZ] * DEG_TO_RAD); - attachment->setRotation(rotation); - } + S32 attachmentID = info->mAttachmentID; + if (attachmentID < 1 || attachmentID > 255) + { + LL_WARNS() << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << LL_ENDL; + continue; + } - int group = info->mGroup; - if (group >= 0) - { - if (group < 0 || group >= 9) - { - LL_WARNS() << "Invalid group number (" << group << ") for attachment point " << info->mName << LL_ENDL; - } - else - { - attachment->setGroup(group); - } - } + LLViewerJointAttachment* attachment = NULL; + bool newly_created = false; + if (mAttachmentPoints.find(attachmentID) == mAttachmentPoints.end()) + { + attachment = new LLViewerJointAttachment(); + newly_created = true; + } + else + { + attachment = mAttachmentPoints[attachmentID]; + } - S32 attachmentID = info->mAttachmentID; - if (attachmentID < 1 || attachmentID > 255) - { - LL_WARNS() << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << LL_ENDL; - delete attachment; - continue; - } - if (mAttachmentPoints.find(attachmentID) != mAttachmentPoints.end()) - { - LL_WARNS() << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << LL_ENDL; - delete attachment; - continue; - } + attachment->setName(info->mName); + LLJoint *parent_joint = getJoint(info->mJointName); + if (!parent_joint) + { + // If the intended parent for attachment point is unavailable, avatar_lad.xml is corrupt. + LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL; + LL_ERRS() << "Invalid avatar_lad.xml file" << LL_ENDL; + } - attachment->setPieSlice(info->mPieMenuSlice); - attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); - attachment->setIsHUDAttachment(info->mIsHUDAttachment); + if (info->mHasPosition) + { + attachment->setOriginalPosition(info->mPosition); + attachment->setDefaultPosition(info->mPosition); + } + + if (info->mHasRotation) + { + LLQuaternion rotation; + rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD, + info->mRotationEuler.mV[VY] * DEG_TO_RAD, + info->mRotationEuler.mV[VZ] * DEG_TO_RAD); + attachment->setRotation(rotation); + } - mAttachmentPoints[attachmentID] = attachment; + int group = info->mGroup; + if (group >= 0) + { + if (group < 0 || group > 9) + { + LL_WARNS() << "Invalid group number (" << group << ") for attachment point " << info->mName << LL_ENDL; + } + else + { + attachment->setGroup(group); + } + } - // now add attachment joint - parentJoint->addChild(attachment); - } - } + attachment->setPieSlice(info->mPieMenuSlice); + attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); + attachment->setIsHUDAttachment(info->mIsHUDAttachment); + // attachment can potentially be animated, needs a number. + attachment->setJointNum(mNumBones + mNumCollisionVolumes + attachmentID - 1); - return TRUE; + if (newly_created) + { + mAttachmentPoints[attachmentID] = attachment; + + // now add attachment joint + parent_joint->addChild(attachment); + } + } } //----------------------------------------------------------------------------- @@ -5921,7 +6478,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) LLUUID mesh_id; if (getRiggedMeshID(pVO, mesh_id)) { - resetJointPositionsOnDetach(mesh_id); + resetJointsOnDetach(mesh_id); if ( gAgentCamera.cameraCustomizeAvatar() ) { gAgent.unpauseAnimation(); @@ -6018,6 +6575,7 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655. sitDown(TRUE); mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject + // SL-315 mRoot->setPosition(getPosition()); mRoot->updateWorldMatrixChildren(); @@ -6076,6 +6634,7 @@ void LLVOAvatar::getOffObject() sitDown(FALSE); mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject + // SL-315 mRoot->setPosition(cur_position_world); mRoot->setRotation(cur_rotation_world); mRoot->getXform()->update(); @@ -6119,7 +6678,6 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) return NULL; } -// warning: order(N) not order(1) S32 LLVOAvatar::getAttachmentCount() { S32 count = mAttachmentPoints.size(); @@ -7122,11 +7680,10 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) wtype = vparam->getWearableType(); } S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); - apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n", - viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(), - LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str() -// param_location_name(vparam->getParamLocation()).c_str() - ); + apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" display=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\" group=\"%d\"/>\n", + viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(), + LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str(), + viewer_param->getGroup()); } @@ -7191,7 +7748,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe U8 av_u8; mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0); contents.mAppearanceVersion = av_u8; - LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL; + //LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL; mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0); // For future use: //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); @@ -7203,7 +7760,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe { LLVector3 hover; mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover); - LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL; + //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL; contents.mHoverOffset = hover; contents.mHoverOffsetWasSet = true; } @@ -7213,7 +7770,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing if( num_blocks > 1 && !drop_visual_params_debug) { - LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; + //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; LLVisualParam* param = getFirstVisualParam(); llassert(param); // if this ever fires, we should do the same as when num_blocks<=1 @@ -7274,7 +7831,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe { S32 index = it - contents.mParams.begin(); contents.mParamAppearanceVersion = ll_round(contents.mParamWeights[index]); - LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL; + //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL; } } } @@ -7303,9 +7860,9 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 { appearance_version = 1; } - LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion - << " param: " << contents.mParamAppearanceVersion - << " final: " << appearance_version << LL_ENDL; + //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion + // << " param: " << contents.mParamAppearanceVersion + // << " final: " << appearance_version << LL_ENDL; return true; } @@ -7326,17 +7883,15 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) mLastAppearanceMessageTimer.reset(); - ESex old_sex = getSex(); - - LLAppearanceMessageContents contents; - parseAppearanceMessage(mesgsys, contents); + LLPointer<LLAppearanceMessageContents> contents(new LLAppearanceMessageContents); + parseAppearanceMessage(mesgsys, *contents); if (enable_verbose_dumps) { - dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents); + dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents); } S32 appearance_version; - if (!resolve_appearance_version(contents, appearance_version)) + if (!resolve_appearance_version(*contents, appearance_version)) { LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL; return; @@ -7348,7 +7903,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) return; } - S32 thisAppearanceVersion(contents.mCOFVersion); + S32 thisAppearanceVersion(contents->mCOFVersion); if (isSelf()) { // In the past this was considered to be the canonical COF version, // that is no longer the case. The canonical version is maintained @@ -7378,7 +7933,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } // SUNSHINE CLEANUP - is this case OK now? - S32 num_params = contents.mParamWeights.size(); + S32 num_params = contents->mParamWeights.size(); if (num_params <= 1) { // In this case, we have no reliable basis for knowing @@ -7390,6 +7945,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } // No backsies zone - if we get here, the message should be valid and usable, will be processed. + // Note: + // RequestAgentUpdateAppearanceResponder::onRequestRequested() + // assumes that cof version is only updated with server-bake + // appearance messages. LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL; // Note: @@ -7399,6 +7958,17 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // of the COF that should be considered canonical. mLastUpdateReceivedCOFVersion = thisAppearanceVersion; + mLastProcessedAppearance = contents; + + bool slam_params = false; + applyParsedAppearanceMessage(*contents, slam_params); +} + +void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params) +{ + S32 num_params = contents.mParamWeights.size(); + ESex old_sex = getSex(); + if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE)) { updateVisualComplexity(); @@ -7428,8 +7998,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; mFirstAppearanceMessageReceived = TRUE; - LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID - << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID + // << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; if (is_first_appearance_message ) { @@ -7442,7 +8012,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // Apply visual params if( num_params > 1) { - LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL; + //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL; BOOL params_changed = FALSE; BOOL interp_params = FALSE; S32 params_changed_count = 0; @@ -7452,12 +8022,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) LLVisualParam* param = contents.mParams[i]; F32 newWeight = contents.mParamWeights[i]; - if (is_first_appearance_message || (param->getWeight() != newWeight)) + if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight)) { params_changed = TRUE; params_changed_count++; - if(is_first_appearance_message) + if(is_first_appearance_message || slam_params) { //LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL; param->setWeight(newWeight); @@ -7542,7 +8112,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } updateMeshTextures(); - //if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end"); } // static @@ -7673,7 +8242,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu if (selfp) { - LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; + //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; } if (!success && selfp) @@ -7691,14 +8260,14 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL; + //LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL; LLUUID id = src_vi->getID(); LLUUID *avatar_idp = (LLUUID *)userdata; LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); if (selfp) { - LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; + //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; } if (selfp && !success) @@ -7807,6 +8376,40 @@ void dump_sequential_xml(const std::string outprefix, const LLSD& content) LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; } +void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& result) const +{ + result.clear(); + if (joint_type==0) + { + avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); + avatar_joint_list_t::const_iterator end = mSkeleton.end(); + for (; iter != end; ++iter) + { + LLJoint* pJoint = (*iter); + result.push_back(pJoint->getName()); + } + } + else if (joint_type==1) + { + for (S32 i = 0; i < mNumCollisionVolumes; i++) + { + LLAvatarJointCollisionVolume* pJoint = &mCollisionVolumes[i]; + result.push_back(pJoint->getName()); + } + } + else if (joint_type==2) + { + for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ++iter) + { + LLViewerJointAttachment* pJoint = iter->second; + if (!pJoint) continue; + result.push_back(pJoint->getName()); + } + } + std::sort(result.begin(), result.end()); +} + void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables ) { std::string outprefix(prefix); @@ -7886,28 +8489,90 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara } } - avatar_joint_list_t::iterator iter = mSkeleton.begin(); - avatar_joint_list_t::iterator end = mSkeleton.end(); - for (; iter != end; ++iter) - { - LLJoint* pJoint = (*iter); + // Root joint + const LLVector3& pos = mRoot->getPosition(); + const LLVector3& scale = mRoot->getScale(); + apr_file_printf( file, "\t\t<root name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n", + mRoot->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + + // Bones + std::vector<std::string> bone_names, cv_names, attach_names, all_names; + getSortedJointNames(0, bone_names); + getSortedJointNames(1, cv_names); + getSortedJointNames(2, attach_names); + all_names.insert(all_names.end(), bone_names.begin(), bone_names.end()); + all_names.insert(all_names.end(), cv_names.begin(), cv_names.end()); + all_names.insert(all_names.end(), attach_names.begin(), attach_names.end()); + + for (std::vector<std::string>::iterator name_iter = bone_names.begin(); + name_iter != bone_names.end(); ++name_iter) + { + LLJoint *pJoint = getJoint(*name_iter); const LLVector3& pos = pJoint->getPosition(); const LLVector3& scale = pJoint->getScale(); - apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n", + apr_file_printf( file, "\t\t<bone name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n", pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); - } + } - for (iter = mSkeleton.begin(); iter != end; ++iter) - { - LLJoint* pJoint = (*iter); + // Collision volumes + for (std::vector<std::string>::iterator name_iter = cv_names.begin(); + name_iter != cv_names.end(); ++name_iter) + { + LLJoint *pJoint = getJoint(*name_iter); + const LLVector3& pos = pJoint->getPosition(); + const LLVector3& scale = pJoint->getScale(); + apr_file_printf( file, "\t\t<collision_volume name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + } + + // Attachment joints + for (std::vector<std::string>::iterator name_iter = attach_names.begin(); + name_iter != attach_names.end(); ++name_iter) + { + LLJoint *pJoint = getJoint(*name_iter); + if (!pJoint) continue; + const LLVector3& pos = pJoint->getPosition(); + const LLVector3& scale = pJoint->getScale(); + apr_file_printf( file, "\t\t<attachment_point name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + } + + // Joint pos overrides + for (std::vector<std::string>::iterator name_iter = all_names.begin(); + name_iter != all_names.end(); ++name_iter) + { + LLJoint *pJoint = getJoint(*name_iter); LLVector3 pos; LLUUID mesh_id; - if (pJoint->hasAttachmentPosOverride(pos,mesh_id)) + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) + { + S32 num_pos_overrides; + std::set<LLVector3> distinct_pos_overrides; + pJoint->getAllAttachmentPosOverrides(num_pos_overrides, distinct_pos_overrides); + apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str(), + num_pos_overrides, (S32) distinct_pos_overrides.size()); + } + } + // Joint scale overrides + for (std::vector<std::string>::iterator name_iter = all_names.begin(); + name_iter != all_names.end(); ++name_iter) + { + LLJoint *pJoint = getJoint(*name_iter); + + LLVector3 scale; + LLUUID mesh_id; + + if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) { - apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\"/>\n", - pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str()); + S32 num_scale_overrides; + std::set<LLVector3> distinct_scale_overrides; + pJoint->getAllAttachmentPosOverrides(num_scale_overrides, distinct_scale_overrides); + apr_file_printf( file, "\t\t<joint_scale name=\"%s\" scale=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n", + pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str(), + num_scale_overrides, (S32) distinct_scale_overrides.size()); } } F32 pelvis_fixup; @@ -8504,7 +9169,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() && (all_textures.find(image_id) == all_textures.end())) { // attachment texture not previously seen. - LL_INFOS() << "attachment_texture: " << image_id.asString() << LL_ENDL; + LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL; all_textures.insert(image_id); } } @@ -8524,7 +9189,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() continue; if (all_textures.find(image_id) == all_textures.end()) { - LL_INFOS() << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL; + LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL; all_textures.insert(image_id); } } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 418cca519d68697664ce31830df290a91e2bceb4..bd89d4ef23ab7b8bd2cad23d0a5546418deb6dc8 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -68,13 +68,11 @@ class LLVoiceVisualizer; class LLHUDNameTag; class LLHUDEffectSpiral; class LLTexGlobalColor; -struct LLVOAvatarBoneInfo; -struct LLVOAvatarChildJoint; -//class LLViewerJoint; + struct LLAppearanceMessageContents; -struct LLVOAvatarSkeletonInfo; class LLViewerJointMesh; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar // @@ -201,11 +199,18 @@ class LLVOAvatar : void dumpAnimationState(); virtual LLJoint* getJoint(const std::string &name); + LLJoint* getJoint(S32 num); - void addAttachmentPosOverridesForObject(LLViewerObject *vo); - void resetJointPositionsOnDetach(const LLUUID& mesh_id); - void resetJointPositionsOnDetach(LLViewerObject *vo); - void clearAttachmentPosOverrides(); + void addAttachmentOverridesForObject(LLViewerObject *vo); + void resetJointsOnDetach(const LLUUID& mesh_id); + void resetJointsOnDetach(LLViewerObject *vo); + bool jointIsRiggedTo(const std::string& joint_name); + bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo); + void clearAttachmentOverrides(); + void rebuildAttachmentOverrides(); + void showAttachmentOverrides(bool verbose = false) const; + void getAttachmentOverrideNames(std::set<std::string>& pos_names, + std::set<std::string>& scale_names) const; /*virtual*/ const LLUUID& getID() const; /*virtual*/ void addDebugText(const std::string& text); @@ -364,10 +369,14 @@ class LLVOAvatar : /*virtual*/ LLAvatarJointMesh* createAvatarJointMesh(); // Returns LLViewerJointMesh public: void updateHeadOffset(); + void debugBodySize() const; void postPelvisSetRecalc( void ); /*virtual*/ BOOL loadSkeletonNode(); + void initAttachmentPoints(bool ignore_hud_joints = false); /*virtual*/ void buildCharacter(); + void resetVisualParams(); + void resetSkeleton(bool reset_animations); LLVector3 mCurRootToHeadOffset; LLVector3 mTargetRootToHeadOffset; @@ -404,6 +413,7 @@ class LLVOAvatar : F32 getLastSkinTime() { return mLastSkinTime; } U32 renderTransparent(BOOL first_pass); void renderCollisionVolumes(); + void renderBones(); void renderJoints(); static void deleteCachedImages(bool clearAll=true); static void destroyGL(); @@ -668,9 +678,12 @@ class LLVOAvatar : ** APPEARANCE **/ + LLPointer<LLAppearanceMessageContents> mLastProcessedAppearance; + public: void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg); void processAvatarAppearance(LLMessageSystem* mesgsys); + void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params); void hideSkirt(); void startAppearanceAnimation(); @@ -964,6 +977,7 @@ class LLVOAvatar : // General //-------------------------------------------------------------------- public: + void getSortedJointNames(S32 joint_type, std::vector<std::string>& result) const; void dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false); void dumpAppearanceMsgParams( const std::string& dump_prefix, const LLAppearanceMessageContents& contents); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 5f48898cb165319a53b9594cfe3d247a8b501b9a..aa5d82a096681b97ced6e22d9a8bbbff8948a33b 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -65,6 +65,7 @@ #include "llsdutil.h" #include "llstartup.h" #include "llsdserialize.h" +#include "llcallstack.h" #include "llcorehttputil.h" #if LL_MSVC @@ -192,6 +193,7 @@ bool update_avatar_rez_metrics() return true; gAgentAvatarp->updateAvatarRezMetrics(false); + return false; } @@ -219,7 +221,6 @@ void LLVOAvatarSelf::initInstance() { mDebugBakedTextureTimes[i][0] = -1.0f; mDebugBakedTextureTimes[i][1] = -1.0f; - mInitialBakeIDs[i] = LLUUID::null; } status &= buildMenus(); @@ -340,6 +341,7 @@ BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info) F32 aspect = LLViewerCamera::getInstance()->getAspect(); LLVector3 scale(1.f, aspect, 1.f); mScreenp->setScale(scale); + // SL-315 mScreenp->setWorldPosition(LLVector3::zero); // need to update screen agressively when sidebar opens/closes, for example mScreenp->mUpdateXform = TRUE; @@ -381,6 +383,10 @@ BOOL LLVOAvatarSelf::buildMenus() params.name(params.label); gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params); + params.label(LLTrans::getString("BodyPartsEnhancedSkeleton")); + params.name(params.label); + gAttachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params); + gDetachBodyPartPieMenus[0] = NULL; params.label(LLTrans::getString("BodyPartsRightArm")); @@ -409,7 +415,11 @@ BOOL LLVOAvatarSelf::buildMenus() params.name(params.label); gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params); - for (S32 i = 0; i < 8; i++) + params.label(LLTrans::getString("BodyPartsEnhancedSkeleton")); + params.name(params.label); + gDetachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params); + + for (S32 i = 0; i < 9; i++) { if (gAttachBodyPartPieMenus[i]) { @@ -494,7 +504,7 @@ BOOL LLVOAvatarSelf::buildMenus() ++iter) { LLViewerJointAttachment* attachment = iter->second; - if (attachment && attachment->getGroup() == 8) + if (attachment->getGroup() == 9) { LLMenuItemCallGL::Params item_params; std::string sub_piemenu_name = attachment->getName(); @@ -580,7 +590,7 @@ BOOL LLVOAvatarSelf::buildMenus() } } - for (S32 group = 0; group < 8; group++) + for (S32 group = 0; group < 9; group++) { // skip over groups that don't have sub menus if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group]) @@ -690,13 +700,23 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) // virtual LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) { - if (mScreenp) + LLJoint *jointp = NULL; + jointp = LLVOAvatar::getJoint(name); + if (!jointp && mScreenp) { - LLJoint* jointp = mScreenp->findJoint(name); - if (jointp) return jointp; + jointp = mScreenp->findJoint(name); + if (jointp) + { + mJointMap[name] = jointp; + } } - return LLVOAvatar::getJoint(name); + if (jointp && jointp != mScreenp && jointp != mRoot) + { + llassert(LLVOAvatar::getJoint((S32)jointp->getJointNum())==jointp); + } + return jointp; } + // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index a9c4ab26a9ac0762f1131ebefd092f2ba3dd1e9d..f9f90bb323a6e99978810cc2320d09334c7424dd 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -103,17 +103,6 @@ class LLVOAvatarSelf : // helper function. Passed in param is assumed to be in avatar's parameter list. BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight); - - -/** Initialization - ** ** - *******************************************************************************/ - -private: - LLUUID mInitialBakeIDs[6]; - //bool mInitialBakesLoaded; - - /******************************************************************************** ** ** ** STATE diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8c026bae2166176ca0c5d64b57d2df0c817b22a2..657babd92cc8bfc89a7bc5401f3a792506f7a3ac 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -54,6 +54,7 @@ #include "llspatialpartition.h" #include "llhudmanager.h" #include "llflexibleobject.h" +#include "llskinningutil.h" #include "llsky.h" #include "lltexturefetch.h" #include "llvector4a.h" @@ -80,7 +81,7 @@ const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; -U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 20; +U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; BOOL gAnimateTextures = TRUE; //extern BOOL gHideSelectedObjects; @@ -4180,27 +4181,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //build matrix palette - static const size_t kMaxJoints = 52; + static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; - LLMatrix4a mp[kMaxJoints]; - LLMatrix4* mat = (LLMatrix4*) mp; - - U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints); - for (U32 j = 0; j < maxJoints; ++j) - { - LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); - if (!joint) - { - // Fall back to a point inside the avatar if mesh is - // rigged to an unknown joint. - joint = avatar->getJoint("mPelvis"); - } - if (joint) - { - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); - } - } + LLMatrix4a mat[kMaxJoints]; + U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { @@ -4212,6 +4197,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if ( weight ) { + LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -4221,40 +4207,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons { LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED); + U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < dst_face.mNumVertices; ++j) { LLMatrix4a final_mat; - final_mat.clear(); - - S32 idx[4]; - - LLVector4 wght; - - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j][k]; - - idx[k] = (S32) floorf(w); - wght[k] = w - floorf(w); - scale += wght[k]; - } - // This is enforced in unpackVolumeFaces() - llassert(scale>0.f); - wght *= 1.f / scale; - - for (U32 k = 0; k < 4; k++) - { - F32 w = wght[k]; - - LLMatrix4a src; - // Insure ref'd bone is in our clamped array of mats - // clamp idx to maxJoints to avoid reading garbage off stack in release - S32 index = llclamp((S32)idx[k],(S32)0,(S32)kMaxJoints-1); - src.setMul(mp[index], w); - final_mat.add(src); - } - + LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; @@ -4812,13 +4769,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) drawablep->clearState(LLDrawable::HAS_ALPHA); bool rigged = vobj->isAttachment() && - vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); + vobj->isMesh() && + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); bool is_rigged = false; + if (rigged && pAvatarVO) + { + pAvatarVO->addAttachmentOverridesForObject(vobj); + if (!LLApp::isExiting() && pAvatarVO->isSelf() && debugLoggingEnabled("AvatarAttachments")) + { + bool verbose = true; + pAvatarVO->showAttachmentOverrides(verbose); + } + } + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -4835,8 +4802,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //sum up face verts and indices drawablep->updateFaceSize(i); - - if (rigged) { if (!facep->isState(LLFace::RIGGED)) @@ -4850,13 +4815,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //get drawpool of avatar with rigged face LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); - // FIXME should this be inside the face loop? - // doesn't seem to depend on any per-face state. - if ( pAvatarVO ) - { - pAvatarVO->addAttachmentPosOverridesForObject(vobj); - } - if (pool) { const LLTextureEntry* te = facep->getTextureEntry(); diff --git a/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml index 2c141f616ff139f2ac250016e3eb5830ea82add1..65a7e255f9bfec29d7cb2e8b6263b91505b135dd 100644 --- a/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Maximale Komplexität:" name="IndirectMaxComplexity" tool_tip="Bestimmt, an welchem Punkt ein visuell komplexer Avatar als „Gummibärchen“ dargestellt wird"/> + <slider label="Maximale Komplexität:" name="IndirectMaxComplexity" tool_tip="Bestimmt, an welchem Punkt ein visuell komplexer Avatar als JellyDoll dargestellt wird"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/de/menu_attachment_other.xml b/indra/newview/skins/default/xui/de/menu_attachment_other.xml index ddb1e7b0b1c112f29c3b5e044e732883d428cdf7..ba1b36db06adec94567567a398b1c60261ec96ab 100644 --- a/indra/newview/skins/default/xui/de/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/de/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Anrufen" name="Call"/> <menu_item_call label="In Gruppe einladen" name="Invite..."/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> <menu_item_call label="Ignorieren" name="Avatar Mute"/> <menu_item_call label="Melden" name="abuse"/> <menu_item_call label="Einfrieren" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/de/menu_attachment_self.xml b/indra/newview/skins/default/xui/de/menu_attachment_self.xml index e0f37b28af7bb9e0a526a76b22b2b58bb6990b1d..cd24e6ad3f5bf8b616b7b157303fec9d91713042 100644 --- a/indra/newview/skins/default/xui/de/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/de/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Mein Outfit bearbeiten" name="Edit Outfit"/> <menu_item_call label="Meine Form bearbeiten" name="Edit My Shape"/> <menu_item_call label="Schwebehöhe" name="Hover Height"/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> <menu_item_call label="Meine Freunde" name="Friends..."/> <menu_item_call label="Meine Gruppen" name="Groups..."/> <menu_item_call label="Mein Profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/de/menu_avatar_other.xml b/indra/newview/skins/default/xui/de/menu_avatar_other.xml index 7242ba1495bcd64b4c0c699c9bb31f4a8e54d331..447655cde7b352c9e483ab1a8be236effb17b7d3 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Anrufen" name="Call"/> <menu_item_call label="In Gruppe einladen" name="Invite..."/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> <menu_item_call label="Ignorieren" name="Avatar Mute"/> <menu_item_call label="Melden" name="abuse"/> <menu_item_call label="Einfrieren" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/de/menu_avatar_self.xml b/indra/newview/skins/default/xui/de/menu_avatar_self.xml index b53f8cd6af9faf038a2f3d7bcb0502a93279b06b..f4a3cc17b890eafad87fc7af18899efaac202e5c 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Mein Outfit bearbeiten" name="Edit Outfit"/> <menu_item_call label="Meine Form bearbeiten" name="Edit My Shape"/> <menu_item_call label="Schwebehöhe" name="Hover Height"/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> <menu_item_call label="Meine Freunde" name="Friends..."/> <menu_item_call label="Meine Gruppen" name="Groups..."/> <menu_item_call label="Mein Profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index d83a6071f6e1a8b75810a16fdbc4597208b91515..319162db34d3183b7f3b0c4e4ecfbe479af1f50c 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Nicht stören" name="Do Not Disturb"/> </menu> <menu_item_call label="L$ kaufen..." name="Buy and Sell L$"/> - <menu_item_call label="Händler-Outbox..." name="MerchantOutbox"/> <menu_item_call label="Marktplatz-Auflistungen..." name="MarketplaceListings"/> <menu_item_call label="Kontoübersicht..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=de"/> @@ -415,6 +414,7 @@ <menu_item_check label="LOD deaktiveren" name="Disable LOD"/> <menu_item_check label="Fehler für sichtbare Agenten beseitigen" name="Debug Character Vis"/> <menu_item_check label="Gelenkpunkte anzeigen" name="Show Collision Skeleton"/> + <menu_item_check label="Knochen anzeigen" name="Show Bones"/> <menu_item_check label="Agent-Ziel anzeigen" name="Display Agent Target"/> <menu_item_call label="Anhänge ausgeben" name="Dump Attachments"/> <menu_item_call label="Fehler in Avatar-Texturen beseitigen" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 6fcd025a945897fae572e1e213db24e38411b4b9..0af00ab7059069368b11dbb9c04011b0313c3820 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -487,6 +487,9 @@ Der Outfit-Ordner enthält keine Kleidung, Körperteile oder Anhänge. <notification name="CannotWearInfoNotComplete"> Sie können das Objekt nicht anziehen, weil es noch nicht geladen wurde. Warten Sie kurz und versuchen Sie es dann noch einmal. </notification> + <notification name="MustEnterPasswordToLogIn"> + Bitte geben Sie zur Anmeldung Ihr Kennwort ein. + </notification> <notification name="MustHaveAccountToLogIn"> Sue haben ein Feld leer gelassen. Sie müssen den Benutzernamen Ihres Avatars eingeben. @@ -555,6 +558,9 @@ Hinweis: Der Cache wird dabei gelöscht/geleert. <notification name="ChangeConnectionPort"> Die Port-Einstellungen werden nach einem Neustart von [APP_NAME] wirksam. </notification> + <notification name="ChangeDeferredDebugSetting"> + Die Debug-Einstellung tritt nach Neustart von [APP_NAME] in Kraft. + </notification> <notification name="ChangeSkin"> Die neue Benutzeroberfläche wird nach einem Neustart von [APP_NAME] angezeigt. </notification> @@ -1380,12 +1386,13 @@ Sie können [SECOND_LIFE] normal verwenden. Andere Benutzer können Sie korrekt <ignore name="ignore" text="Das Herunterladen der Kleidung dauert lange"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 visuelle Komplexität] ist [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Avatarkomplexität] ist [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Warnen, falls Avatarkomplexität zu hoch ist" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 visuelle Komplexität] ist [AGENT_COMPLEXITY]. + Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Avatarkomplexität] ist [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> Installation von [APP_NAME] vollständig abgeschlossen. @@ -1501,6 +1508,10 @@ Ersetzen Sie die Textur [TEXTURE_NUM] mit einer Bilddatei von maximal 512x512 un Möchten Sie das aktuelle Terrain formen, es zum Mittelpunkt der oberen und unteren Terraingrenzen und zum Standard des „Zurücksetzen“-Tools machen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Sie sind dabei, für Höhenbereiche untere Werte anzugeben, die größer sind als die oberen Werte. Fortfahren? + <usetemplate canceltext="Nicht fragen" name="yesnocancelbuttons" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Es sind maximal [MAX_AGENTS] zulässige Einwohner erlaubt. </notification> @@ -1735,14 +1746,6 @@ Diese Gruppe verlassen? Sie können die Gruppe nicht verlassen, da Sie der letzte Besitzer der Gruppe sind. Weisen Sie die Besitzerrolle zuerst einem anderen Mitglied zu. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - Kann Gruppe nicht verlassen: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Sie haben die Gruppe „[group_name]“ verlassen. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> Möchten Sie WIRKLICH alle Benutzer aus dem Grid werfen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Alle Benutzer hinauswerfen"/> @@ -2415,6 +2418,10 @@ Möchten Sie den Nicht-stören-Modus deaktivieren, bevor Sie diese Transaktion a Sind Sie sicher, dass Sie den Inhalt Ihres Papierkorbs löschen möchten? <usetemplate ignoretext="Bestätigen, bevor der Ordner Papierkorb im Inventar geleert wird" name="okcancelignore" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Ihr Papierkorb läuft über. Dies kann zu Anmeldeproblemen führen. + <usetemplate name="okcancelbuttons" notext="Papierkorb später leeren" yestext="Papierkorb jetzt leeren"/> + </notification> <notification name="ConfirmClearBrowserCache"> Sind Sie sicher, dass Sie Ihren Reise-, Internet- und Suchverlauf löschen möchten? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> @@ -3272,11 +3279,15 @@ Diese werden für ein paar Sekunden sicherheitshalber gesperrt. <notification name="AttachmentSaved"> Der Anhang wurde gespeichert. </notification> - <notification name="PresetNotSaved"> - Fehler beim Speichern der Voreinstellung [NAME]. + <notification name="AppearanceToXMLSaved"> + Erscheinungsbild als XML in [PATH] gespeichert </notification> - <notification name="PresetNotDeleted"> - Fehler beim Löschen der Voreinstellung [NAME]. + <notification name="AppearanceToXMLFailed"> + Fehler beim Speichern des Erscheinungsbilds als XML. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +Fehler beim Löschen der Voreinstellung [NAME]. </notification> <notification name="UnableToFindHelpTopic"> Hilfethema für dieses Element wurde nicht gefunden. @@ -4089,6 +4100,9 @@ Warten Sie kurz und versuchen Sie es noch einmal. <notification name="CantAttachNotEnoughScriptResources"> Nicht genügend Skriptressourcen verfügbar, um Objekt anzuhängen. </notification> + <notification name="IllegalAttachment"> + Der Anhang hat einen nicht vorhandenen Punkt auf dem Avatar angefordert. Der Anhang wurde stattdessen auf der Brust angebracht. + </notification> <notification name="CantDropItemTrialUser"> Ablegen von Objekten hier nicht möglich; versuchen Sie es mit dem kostenlosen Testbereich. </notification> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml index fcb45e26be25cf01ef1f9cce9b9809c886bf5c76..508e87a8b70a4d86a7e13119fcfd46a3ce5c850a 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Anzeigen: </text> - <check_box label="Wenn ich L$ ausgebe oder erhalte" name="notify_money_change_checkbox"/> + <check_box label="Wenn ich L$ ausgebe" name="notify_money_spend_checkbox"/> <check_box label="Wenn meine Freunde sich an- oder abmelden" name="friends_online_notify_checkbox"/> + <check_box label="Wenn ich L$ erhalte" name="notify_money_received_checkbox"/> <text name="show_label"> Immer anzeigen: </text> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml index 06fd22141f6168a9b39c8464e762a279b03357eb..74fb4d0f858739bab3b6e0032bdea4cf61ad80e3 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Besser </text> + <slider label="Maximale Avatarkomplexität:" name="IndirectMaxComplexity" tool_tip="Bestimmt, an welchem Punkt ein visuell komplexer Avatar als JellyDoll dargestellt wird"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Atmosphären-Shader" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Erweitertes Beleuchtungsmodell" name="UseLightShaders"/> <button label="Einstellungen als Voreinstellung speichern..." name="PrefSaveButton"/> <button label="Voreinstellung laden..." name="PrefLoadButton"/> + min_val="0.125" <button label="Voreinstellung löschen..." name="PrefDeleteButton"/> <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/> <button label="Erweiterte Einstellungen..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/de/panel_sound_devices.xml b/indra/newview/skins/default/xui/de/panel_sound_devices.xml index b739b6197fa30b384b6041c98f6e950554e86bb7..df4b30383eb56be892215398e3022df84f2595e7 100644 --- a/indra/newview/skins/default/xui/de/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/de/panel_sound_devices.xml @@ -16,9 +16,9 @@ Ausgabe </text> <text name="My volume label"> - Meine Lautstärke: + Mikrofonlautstärke: </text> - <slider_bar initial_value="1,0" name="mic_volume_slider" tool_tip="Lautstärke mit diesem Regler ändern"/> + <slider_bar initial_value="1,0" name="mic_volume_slider" tool_tip="Mit diesem Schieberegler können Sie den Mikrofonpegel ändern"/> <text name="wait_text"> Bitte warten </text> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 810022525a76875980a919f0556f829c6e138806..9dd94d223036407ca64035b45ef2f9a47bc71db8 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + Build-Konfiguration [BUILD_CONFIG] + </string> <string name="AboutPosition"> Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -72,6 +75,9 @@ Voice-Server-Version: [VOICE_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> Fehler beim Abrufen der URL für die Server-Versionshinweise. </string> + <string name="BuildConfiguration"> + Build-Konfiguration + </string> <string name="ProgressRestoring"> Wird wiederhergestellt... </string> @@ -1390,6 +1396,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="BodyPartsRightLeg"> Rechtes Bein </string> + <string name="BodyPartsEnhancedSkeleton"> + Erweitertes Skelett + </string> <string name="GraphicsQualityLow"> Niedrig </string> @@ -1838,6 +1847,51 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="Avatar Center"> Avatar-Mitte </string> + <string name="Left Ring Finger"> + Linker Ringfinger + </string> + <string name="Right Ring Finger"> + Rechter Ringfinger + </string> + <string name="Tail Base"> + Schwanzansatz + </string> + <string name="Tail Tip"> + Schwanzspitze + </string> + <string name="Left Wing"> + Linker Flügel + </string> + <string name="Right Wing"> + Rechter Flügel + </string> + <string name="Jaw"> + Kiefer + </string> + <string name="Alt Left Ear"> + Alt. linkes Ohr + </string> + <string name="Alt Right Ear"> + Alt. rechtes Ohr + </string> + <string name="Alt Left Eye"> + Alt. linkes Auge + </string> + <string name="Alt Right Eye"> + Alt. rechtes Auge + </string> + <string name="Tongue"> + Zunge + </string> + <string name="Groin"> + Leiste + </string> + <string name="Left Hind Foot"> + Linker hinterer Fuß + </string> + <string name="Right Hind Foot"> + Rechter hinterer Fuß + </string> <string name="Invalid Attachment"> Ungültige Stelle für Anhang </string> @@ -2227,12 +2281,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ATTACH_BELLY"> Bauch </string> - <string name="ATTACH_RPEC"> - Rechts - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Linke Brust </string> + <string name="ATTACH_RIGHT_PEC"> + Rechte Brust + </string> <string name="ATTACH_HUD_CENTER_2"> HUD Mitte 2 </string> @@ -2263,6 +2317,51 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ATTACH_AVATAR_CENTER"> Avatar-Mitte </string> + <string name="ATTACH_LHAND_RING1"> + Linker Ringfinger + </string> + <string name="ATTACH_RHAND_RING1"> + Rechter Ringfinger + </string> + <string name="ATTACH_TAIL_BASE"> + Schwanzansatz + </string> + <string name="ATTACH_TAIL_TIP"> + Schwanzspitze + </string> + <string name="ATTACH_LWING"> + Linker Flügel + </string> + <string name="ATTACH_RWING"> + Rechter Flügel + </string> + <string name="ATTACH_FACE_JAW"> + Kiefer + </string> + <string name="ATTACH_FACE_LEAR"> + Alt. linkes Ohr + </string> + <string name="ATTACH_FACE_REAR"> + Alt. rechtes Ohr + </string> + <string name="ATTACH_FACE_LEYE"> + Alt. linkes Auge + </string> + <string name="ATTACH_FACE_REYE"> + Alt. rechtes Auge + </string> + <string name="ATTACH_FACE_TONGUE"> + Zunge + </string> + <string name="ATTACH_GROIN"> + Leiste + </string> + <string name="ATTACH_HIND_LFOOT"> + Linker hinterer Fuß + </string> + <string name="ATTACH_HIND_RFOOT"> + Rechter hinterer Fuß + </string> <string name="CursorPos"> Zeile [LINE], Spalte [COLUMN] </string> @@ -4252,6 +4351,12 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="OfflineStatus"> Offline </string> + <string name="not_online_msg"> + Benutzer nicht online – Nachricht wird gespeichert und später zugestellt. + </string> + <string name="not_online_inventory"> + Benutzer nicht online – Inventar gespeichert. + </string> <string name="answered_call"> Ihr Anruf wurde entgegengenommen </string> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index d2c8dddfe10d8f5348b74c1c811178bbcc97e2be..2750316f2e74fe684d026b9ba02539805191c52b 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1217,6 +1217,13 @@ label_text.text_color="White" name="upload_joints" top_pad="15"/> + <check_box + follows="top|left" + height="15" + label="Lock scale if joint position defined" + label_text.text_color="White" + name="lock_scale_if_joint_position" + top_pad="15"/> <text follows="top|left" height="15" diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 638a4e2da88ceca6d7278498fce3392d5a23561a..9a9101e0da1f71e9f54012634d8a457562c4fe25 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -3,7 +3,7 @@ legacy_header_height="18" positioning="centered" default_tab_group="1" - height="460" + height="512" layout="topleft" name="Preferences" help_topic="preferences" @@ -19,7 +19,7 @@ layout="topleft" right="-105" name="OK" - top="433" + top="473" width="90"> <button.commit_callback function="Pref.OK" /> @@ -40,7 +40,7 @@ <tab_container follows="all" halign="left" - height="410" + height="440" layout="topleft" left="0" name="pref core" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 9e520b2d31b22c39e03acd5bf4986f2fc6a06047..2f60bab0b7e7fa36ca63455994e8d8cf90b49d52 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -39,6 +39,22 @@ <menu_item_call.on_click function="Avatar.InviteToGroup" /> </menu_item_call> + <menu_item_separator /> + + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_separator /> <menu_item_call enabled="false" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index c6ae844d676dc6385f8181134975fd69f924cce0..59faf6a9f58664872e5498e75bf022dec8f550c2 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -99,6 +99,19 @@ name="Edit Outfit"> <menu_item_call.on_enable function="Edit.EnableHoverHeight" /> </menu_item_call> + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_call label="My Friends" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index fadacbf3cb79122f42ec226343fab8bd2b8d7f68..ddfff234100b30cd41e99d8459ac4e66419ab714 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -40,6 +40,22 @@ function="Avatar.InviteToGroup" /> </menu_item_call> + <menu_item_separator /> + + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_separator /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index d3b0b07f700f461fc7c55619de2443b61a9bcfb9..9e181d0b6d139f372285bf41b97eaea760efe32b 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -237,6 +237,18 @@ <menu_item_call.on_enable function="Edit.EnableHoverHeight" /> </menu_item_call> + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> <menu_item_call label="My Friends" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8a649a57d1874fd14afddf1e09b8427fc085b3a8..ea826d2243843b323599b428ee2a235ba0185275 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3510,6 +3510,16 @@ function="Advanced.ToggleInfoDisplay" parameter="collision skeleton" /> </menu_item_check> + <menu_item_check + label="Show Bones" + name="Show Bones"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="joints" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="joints" /> + </menu_item_check> <menu_item_check label="Display Agent Target" name="Display Agent Target"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 804235518e8cd4b78a088647cc08a70f797ca414..11e019e153bf213bdf93d1c008fc0618b0c0d69e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1437,6 +1437,13 @@ Note: This will clear the cache. Port settings take effect after you restart [APP_NAME]. </notification> + <notification + icon="alertmodal.tga" + name="ChangeDeferredDebugSetting" + type="alertmodal"> +This debug setting change will take effect after you restart [APP_NAME]. + </notification> + <notification icon="alertmodal.tga" name="ChangeSkin" @@ -10500,6 +10507,14 @@ Not enough script resources available to attach object! Cannot attach object because it is already being removed. </notification> + <notification + icon="alertmodal.tga" + name="IllegalAttachment" + type="notify"> + <tag>fail</tag> + The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead. + </notification> + <notification icon="alertmodal.tga" name="CantDropItemTrialUser" diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml index 94c468e1bb0d06e189cc7d6cfeeee4ae94a13f8d..756b8f81026e2147b25f18929f2c4393970ce305 100644 --- a/indra/newview/skins/default/xui/en/panel_notification.xml +++ b/indra/newview/skins/default/xui/en/panel_notification.xml @@ -10,7 +10,6 @@ left="0" name="notification_panel" chrome="true" - show_title="false" top="0" height="140" translate="false" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index e002d9dee10616c1f40243b956f15b84cc8df28c..32cbbff8b772cb5280241dff48ce6be9888c3a2c 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -2,7 +2,7 @@ <panel border="true" follows="left|top|right|bottom" - height="418" + height="438" label="Graphics" layout="topleft" left="102" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 323da2be38be875d17dc5f9634754ca5f01ddf3d..284688d4d15b4026bcb2ff9ca62e82acbdb3d681 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -16,7 +16,7 @@ </panel.string> <button - follows="left|bottom" + follows="left|top" height="23" label="Clear History" tool_tip="Clear login image, last location, teleport history, web, and texture cache" @@ -75,7 +75,7 @@ top_pad="10" width="350" /> <button - follows="left|bottom" + follows="left|top" height="23" label="Block list" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 615abbaa895c6bbfe42f17451ac966a67feeeeb3..53b74fa645693372f9b6f979e559d020ec2c21aa 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -2,7 +2,7 @@ <panel border="true" follows="all" - height="408" + height="438" label="Sounds" layout="topleft" left="102" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 9b3fb06bdf11a8f1a7a091e8a74d3abeecc43589..dcb259f2bbe8c4babdb27517e0641fa30f66282c 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2258,6 +2258,7 @@ For AI Character: Get the closest navigable point to the point provided. <string name="BodyPartsLeftLeg">Left Leg</string> <string name="BodyPartsTorso">Torso</string> <string name="BodyPartsRightLeg">Right Leg</string> + <string name="BodyPartsEnhancedSkeleton">Enhanced Skeleton</string> <!-- slider --> <string name="GraphicsQualityLow">Low</string> @@ -2479,8 +2480,23 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="Stomach">Stomach</string> <string name="Left Pec">Left Pec</string> <string name="Right Pec">Right Pec</string> - <string name="Neck">Neck</string> - <string name="Avatar Center">Avatar Center</string> + <string name="Neck">Neck</string> + <string name="Avatar Center">Avatar Center</string> + <string name="Left Ring Finger">Left Ring Finger</string> + <string name="Right Ring Finger">Right Ring Finger</string> + <string name="Tail Base">Tail Base</string> + <string name="Tail Tip">Tail Tip</string> + <string name="Left Wing">Left Wing</string> + <string name="Right Wing">Right Wing</string> + <string name="Jaw">Jaw</string> + <string name="Alt Left Ear">Alt Left Ear</string> + <string name="Alt Right Ear">Alt Right Ear</string> + <string name="Alt Left Eye">Alt Left Eye</string> + <string name="Alt Right Eye">Alt Right Eye</string> + <string name="Tongue">Tongue</string> + <string name="Groin">Groin</string> + <string name="Left Hind Foot">Left Hind Foot</string> + <string name="Right Hind Foot">Right Hind Foot</string> <string name="Invalid Attachment">Invalid Attachment Point</string> <string name="ATTACHMENT_MISSING_ITEM">Error: missing item</string> <string name="ATTACHMENT_MISSING_BASE_ITEM">Error: missing base item</string> @@ -2666,8 +2682,8 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="ATTACH_LULEG">Left Upper Leg</string> <string name="ATTACH_LLLEG">Left Lower Leg</string> <string name="ATTACH_BELLY">Belly</string> - <string name="ATTACH_RPEC">Right Pec</string> - <string name="ATTACH_LPEC">Left Pec</string> + <string name="ATTACH_LEFT_PEC">Left Pec</string> + <string name="ATTACH_RIGHT_PEC">Right Pec</string> <string name="ATTACH_HUD_CENTER_2">HUD Center 2</string> <string name="ATTACH_HUD_TOP_RIGHT">HUD Top Right</string> <string name="ATTACH_HUD_TOP_CENTER">HUD Top Center</string> @@ -2678,6 +2694,21 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string> <string name="ATTACH_NECK">Neck</string> <string name="ATTACH_AVATAR_CENTER">Avatar Center</string> + <string name="ATTACH_LHAND_RING1">Left Ring Finger</string> + <string name="ATTACH_RHAND_RING1">Right Ring Finger</string> + <string name="ATTACH_TAIL_BASE">Tail Base</string> + <string name="ATTACH_TAIL_TIP">Tail Tip</string> + <string name="ATTACH_LWING">Left Wing</string> + <string name="ATTACH_RWING">Right Wing</string> + <string name="ATTACH_FACE_JAW">Jaw</string> + <string name="ATTACH_FACE_LEAR">Alt Left Ear</string> + <string name="ATTACH_FACE_REAR">Alt Right Ear</string> + <string name="ATTACH_FACE_LEYE">Alt Left Eye</string> + <string name="ATTACH_FACE_REYE">Alt Right Eye</string> + <string name="ATTACH_FACE_TONGUE">Tongue</string> + <string name="ATTACH_GROIN">Groin</string> + <string name="ATTACH_HIND_LFOOT">Left Hind Foot</string> + <string name="ATTACH_HIND_RFOOT">Right Hind Foot</string> <!-- script editor --> <string name="CursorPos">Line [LINE], Column [COLUMN]</string> diff --git a/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml index dda95ad0707a1788b8a8d9b96b46a31f29c16eb7..84b256c8e3ab86b441bc4a9614d86e95197370c4 100644 --- a/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complejidad máxima:" name="IndirectMaxComplexity" tool_tip="Controla en qué momento un avatar visualmente complejo se dibuja como una sombra de color sólido"/> + <slider label="Complejidad máxima:" name="IndirectMaxComplexity" tool_tip="Controla en qué momento un avatar visualmente complejo se dibuja como un "JellyDoll""/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/es/menu_attachment_other.xml b/indra/newview/skins/default/xui/es/menu_attachment_other.xml index 772b27c9ba53dc7c62eaa9dd7989b9c673eac30c..c92583cfc30d31bf965f7c71bdc6761f84984b71 100644 --- a/indra/newview/skins/default/xui/es/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/es/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Llamada" name="Call"/> <menu_item_call label="Invitar al grupo" name="Invite..."/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> <menu_item_call label="Ignorar" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/es/menu_attachment_self.xml b/indra/newview/skins/default/xui/es/menu_attachment_self.xml index 02819e6816d40847e75394b7f5827153879fd9a6..a4d09a44ab2c55a1a384d0f31817376d38452d22 100644 --- a/indra/newview/skins/default/xui/es/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/es/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Editar mi vestuario" name="Edit Outfit"/> <menu_item_call label="Editar mi anatomÃa" name="Edit My Shape"/> <menu_item_call label="Altura del avatar" name="Hover Height"/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> <menu_item_call label="Mis amigos" name="Friends..."/> <menu_item_call label="Mis grupos" name="Groups..."/> <menu_item_call label="Mi perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/es/menu_avatar_other.xml b/indra/newview/skins/default/xui/es/menu_avatar_other.xml index 75cbf5a0223305a5bc6645fdc88d1f5bb8195734..e5aef0391194ab95c5426ecca0d0171991d7889b 100644 --- a/indra/newview/skins/default/xui/es/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/es/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Llamada" name="Call"/> <menu_item_call label="Invitar al grupo" name="Invite..."/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> <menu_item_call label="Ignorar" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/es/menu_avatar_self.xml b/indra/newview/skins/default/xui/es/menu_avatar_self.xml index d60a3434cf30b79f92ddb216246baf5f254432aa..ab1496621721d57652ffcd78639df1aaa6031391 100644 --- a/indra/newview/skins/default/xui/es/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/es/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Editar mi vestuario" name="Edit Outfit"/> <menu_item_call label="Editar mi anatomÃa" name="Edit My Shape"/> <menu_item_call label="Altura del avatar" name="Hover Height"/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> <menu_item_call label="Mis amigos" name="Friends..."/> <menu_item_call label="Mis grupos" name="Groups..."/> <menu_item_call label="Mi perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index fd248116b8728a3ef012c001d5bb36304e6edc2b..07c358615c2c087d73858a203b309da68151d369 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -367,6 +367,7 @@ <menu_item_check label="Animation Info" name="Animation Info"/> <menu_item_check label="Disable Level Of Detail" name="Disable LOD"/> <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> + <menu_item_check label="Mostrar los huesos" name="Show Bones"/> <menu_item_check label="Display Agent Target" name="Display Agent Target"/> <menu_item_call label="Debug Avatar Textures" name="Debug Avatar Textures"/> </menu> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index b52497eb85ebe2d0e2f38f330801df9b85f16673..a67e4108146c4b0592c02e902156ba7c3a170eef 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -477,6 +477,9 @@ Se ha superado el lÃmite máximo de [MAX_ATTACHMENTS] objetos. Por favor, quÃt <notification name="CannotWearInfoNotComplete"> No puedes vestirte este Ãtem porque aún no se ha cargado. Por favor, inténtalo de nuevo en un minuto. </notification> + <notification name="MustEnterPasswordToLogIn"> + Escribe la contraseña para poder iniciar sesión. + </notification> <notification name="MustHaveAccountToLogIn"> Lo sentimos. Se ha quedado algún espacio en blanco. Tienes que volver a introducir el nombre de usuario de tu avatar. @@ -545,6 +548,9 @@ Nota: esto vaciará la caché. <notification name="ChangeConnectionPort"> La configuración del puerto tendrá efecto cuando reinicies [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + El cambio de configuración del depurador se activará cuando reinicies [APP_NAME]. + </notification> <notification name="ChangeSkin"> Verás la nueva apariencia cuando reinicies [APP_NAME]. </notification> @@ -1370,12 +1376,13 @@ Puedes usar [SECOND_LIFE] de forma normal; los demás residentes te verán corre <ignore name="ignore" text="La ropa está tardando mucho en descargarse"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Tu [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad visual] es [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad de tu avatar] es [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avisarme si la complejidad de mi avatar puede ser excesiva" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Tu [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad visual] es [AGENT_COMPLEXITY]. + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad de tu avatar] es [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> Se ha completado la instalación de [SECOND_LIFE]. @@ -1492,6 +1499,10 @@ Cambia la textura [TEXTURE_NUM] por una imagen de 24-bit y 512x512 o menor, y pu ¿Realmente quieres predeterminar el terreno actual, haciéndolo el centro de los limites para elevarlo y rebajarlo, y el terreno por defecto para la herramienta 'Revertir'? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Vas a usar valores inferiores más grandes que los de Intervalos de elevación. ¿Quieres continuar? + <usetemplate canceltext="No preguntar" name="yesnocancelbuttons" notext="Cancelar" yestext="Aceptar"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Sólo puedes tener [MAX_AGENTS] residentes autorizados. </notification> @@ -1729,14 +1740,6 @@ Si estás impaciente por probar las nuevas funciones y correcciones, lee la pág No es posible abandonar el grupo. No puedes abandonarlo porque eres su último propietario. Antes tienes que asignar el papel de propietario a otro miembro. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - No se puede abandonar el grupo: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Has abandonado el grupo [group_name]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> ¿Quieres realmente expulsar a todos los residentes de la cuadrÃcula? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Expulsar a todos los Residentes"/> @@ -2409,6 +2412,10 @@ Linden Lab ¿Estás seguro de que quieres borrar de forma permanente el contenido de la Papelera? <usetemplate ignoretext="Confirmar antes de vaciar la Papelera del inventario" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + La papelera está completamente llena. Esto puede causar problemas a la hora de iniciar sesión. + <usetemplate name="okcancelbuttons" notext="Vaciaré la papelera más adelante" yestext="Vaciar la papelera"/> + </notification> <notification name="ConfirmClearBrowserCache"> ¿Estás seguro de que quieres borrar tu historial web, de viajes y de búsquedas? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> @@ -2996,7 +3003,7 @@ Si permaneces en esta región serás desconectado. [MESSAGE] -Del objeto: <nolink>[OBJECTNAME]</nolink>, propietario: [NAME_SLURL] +De objeto: <nolink>[OBJECTNAME]</nolink>, propietario: [NAME_SLURL] <form name="form"> <button name="Gotopage" text="Cargar"/> <button name="Cancel" text="Cancelar"/> @@ -3258,11 +3265,15 @@ Por tu seguridad, serán bloqueadas durante unos segundos. <notification name="AttachmentSaved"> Se ha guardado el adjunto. </notification> - <notification name="PresetNotSaved"> - Error al guardar el valor predefinido [NAME]. + <notification name="AppearanceToXMLSaved"> + El aspecto se ha guardado como XML en [PATH] </notification> - <notification name="PresetNotDeleted"> - Error al eliminar el valor predefinido [NAME]. + <notification name="AppearanceToXMLFailed"> + Error al guardar el aspecto como XML. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +Error al eliminar el valor predefinido [NAME]. </notification> <notification name="UnableToFindHelpTopic"> No se ha podido encontrar un tema de ayuda para este elemento. @@ -4074,6 +4085,9 @@ Prueba otra vez dentro de un minuto. <notification name="CantAttachNotEnoughScriptResources"> No hay suficientes recursos de script disponibles para anexar el objeto </notification> + <notification name="IllegalAttachment"> + El anexo ha solicitado un punto que no existe en el avatar. Por tanto, se ha anexado al pecho. + </notification> <notification name="CantDropItemTrialUser"> No se pueden soltar objetos aquÃ; inténtalo en la zona de prueba gratuita. </notification> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml index f34edf149e57319e9d9e8b408751f53b4ae11ad3..c5b27ae766d342b6d5ea352d6e8c40f7017e922f 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Avisarme: </text> - <check_box label="Cuando gaste o consiga L$" name="notify_money_change_checkbox"/> + <check_box label="Cuando gaste L$" name="notify_money_spend_checkbox"/> <check_box label="Cuando mis amigos se conecten o desconecten" name="friends_online_notify_checkbox"/> + <check_box label="Cuando gane L$" name="notify_money_received_checkbox"/> <text name="show_label" width="300"> Mostrar siempre: </text> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml index f7fb8ab70d73fb62ab01a54b6b1a23ad13a5c476..2db4274e44d66de49772ab481556d4271a4c67d4 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Más calidad </text> + <slider label="Complejidad máxima de avatar:" name="IndirectMaxComplexity" tool_tip="Controla en qué momento un avatar visualmente complejo se dibuja como un "JellyDoll""/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Shaders de la atmósfera" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modelo de iluminación avanzado" name="UseLightShaders"/> <button label="Guardar configuración como valor predefinido..." name="PrefSaveButton"/> <button label="Cargar predefinido..." name="PrefLoadButton"/> + min_val="0.125" <button label="Eliminar predefinido..." name="PrefDeleteButton"/> <button label="Restablecer la configuración recomendada" name="Defaults"/> <button label="Configuración avanzada..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/es/panel_sound_devices.xml b/indra/newview/skins/default/xui/es/panel_sound_devices.xml index 9531b99cc8007adda8705005c0434a609dfe319c..109dcb565a3fff5afcc45a786b7e1318b69678a6 100644 --- a/indra/newview/skins/default/xui/es/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/es/panel_sound_devices.xml @@ -16,9 +16,9 @@ Salida </text> <text name="My volume label"> - Mi volumen: + Volumen de mic.: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia el volumen usando este deslizable"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia el volumen del micrófono con este controlador deslizante"/> <text name="wait_text"> Por favor, espera </text> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index ea6cea060b31996cecebb2a57dd21e4144e817f6..4e20793d86cc56826d97f63a6118afed404c33b4 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -32,6 +32,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + Configuración de constitución [BUILD_CONFIG] + </string> <string name="AboutPosition"> Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -55,7 +58,7 @@ Tarjeta gráfica: [GRAPHICS_CARD] Versión de J2C Decoder: [J2C_VERSION] Versión de Audio Driver: [AUDIO_DRIVER_VERSION] Versión de LLCEFLib/CEF: [LLCEFLIB_VERSION] -Versión del servidor de voz: [VOICE_VERSION] +Versión de Voice Server: [VOICE_VERSION] </string> <string name="AboutTraffic"> Paquetes perdidos: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -63,6 +66,9 @@ Versión del servidor de voz: [VOICE_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> Error al obtener la URL de las notas de la versión del servidor. </string> + <string name="BuildConfiguration"> + Configuración de constitución + </string> <string name="ProgressRestoring"> Restaurando... </string> @@ -1372,6 +1378,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="BodyPartsRightLeg"> Pierna der. </string> + <string name="BodyPartsEnhancedSkeleton"> + Esqueleto mejorado + </string> <string name="GraphicsQualityLow"> Bajo </string> @@ -1814,6 +1823,51 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="Avatar Center"> Centro del avatar </string> + <string name="Left Ring Finger"> + Dedo anular izquierdo + </string> + <string name="Right Ring Finger"> + Dedo anular derecho + </string> + <string name="Tail Base"> + Base de la cola + </string> + <string name="Tail Tip"> + Extremo de la cola + </string> + <string name="Left Wing"> + Ala izquierda + </string> + <string name="Right Wing"> + Ala derecha + </string> + <string name="Jaw"> + MandÃbula + </string> + <string name="Alt Left Ear"> + Oreja izquierda alternativa + </string> + <string name="Alt Right Ear"> + Oreja derecha alternativa + </string> + <string name="Alt Left Eye"> + Ojo izquierdo alternativo + </string> + <string name="Alt Right Eye"> + Ojo derecho alternativo + </string> + <string name="Tongue"> + Lengua + </string> + <string name="Groin"> + Ingle + </string> + <string name="Left Hind Foot"> + Pata trasera izquierda + </string> + <string name="Right Hind Foot"> + Pata trasera derecha + </string> <string name="Invalid Attachment"> Punto de colocación no válido </string> @@ -2203,11 +2257,11 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ATTACH_BELLY"> Vientre </string> - <string name="ATTACH_RPEC"> - Pecho derecho + <string name="ATTACH_LEFT_PEC"> + Pectoral izquierdo </string> - <string name="ATTACH_LPEC"> - Pecho izquierdo + <string name="ATTACH_RIGHT_PEC"> + Pectoral derecho </string> <string name="ATTACH_HUD_CENTER_2"> HUD: Centro 2 @@ -2239,6 +2293,51 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ATTACH_AVATAR_CENTER"> Centro del avatar </string> + <string name="ATTACH_LHAND_RING1"> + Dedo anular izquierdo + </string> + <string name="ATTACH_RHAND_RING1"> + Dedo anular derecho + </string> + <string name="ATTACH_TAIL_BASE"> + Base de la cola + </string> + <string name="ATTACH_TAIL_TIP"> + Extremo de la cola + </string> + <string name="ATTACH_LWING"> + Ala izquierda + </string> + <string name="ATTACH_RWING"> + Ala derecha + </string> + <string name="ATTACH_FACE_JAW"> + MandÃbula + </string> + <string name="ATTACH_FACE_LEAR"> + Oreja izquierda alternativa + </string> + <string name="ATTACH_FACE_REAR"> + Oreja derecha alternativa + </string> + <string name="ATTACH_FACE_LEYE"> + Ojo izquierdo alternativo + </string> + <string name="ATTACH_FACE_REYE"> + Ojo derecho alternativo + </string> + <string name="ATTACH_FACE_TONGUE"> + Lengua + </string> + <string name="ATTACH_GROIN"> + Ingle + </string> + <string name="ATTACH_HIND_LFOOT"> + Pata trasera izquierda + </string> + <string name="ATTACH_HIND_RFOOT"> + Pata trasera derecha + </string> <string name="CursorPos"> LÃnea [LINE], Columna [COLUMN] </string> @@ -4165,6 +4264,12 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. <string name="OfflineStatus"> Desconectado/a </string> + <string name="not_online_msg"> + El usuario no está conectado: el mensaje se almacenará para entregárselo más tarde. + </string> + <string name="not_online_inventory"> + El usuario no está conectado: el inventario se ha guardado. + </string> <string name="answered_call"> Han respondido a tu llamada </string> diff --git a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml index 5c5af022cadd0fef7b78cd5e945f72f97c06b608..d3c4dcfa272f2686c38a54c7f2cc9600bb710c8d 100644 --- a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complexité max. :" name="IndirectMaxComplexity" tool_tip="Contrôle à quel moment un avatar complexe est représenté comme un « jelly doll » (forme de couleur unie)"/> + <slider label="Complexité max. :" name="IndirectMaxComplexity" tool_tip="Contrôle à quel moment un avatar complexe est représenté comme un « jelly baby »"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_other.xml b/indra/newview/skins/default/xui/fr/menu_attachment_other.xml index 20de34250a6e56abd529c3cdbf5b13204aa3f874..fd8112429e71f80a5840f5bb3681f6e7e65709c3 100644 --- a/indra/newview/skins/default/xui/fr/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/fr/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Appeler" name="Call"/> <menu_item_call label="Inviter dans le groupe" name="Invite..."/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> <menu_item_call label="Ignorer" name="Avatar Mute"/> <menu_item_call label="Signaler" name="abuse"/> <menu_item_call label="Figer" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml index 1ccba0809915c342171cf303b5b2687a7c35fe96..f3089ad3bb944faadd4bf6232994614951edb66c 100644 --- a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Modifier ma tenue" name="Edit Outfit"/> <menu_item_call label="Modifier ma silhouette" name="Edit My Shape"/> <menu_item_call label="Hauteur de sustentation" name="Hover Height"/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> <menu_item_call label="Mes amis" name="Friends..."/> <menu_item_call label="Mes groupes" name="Groups..."/> <menu_item_call label="Mon profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_other.xml b/indra/newview/skins/default/xui/fr/menu_avatar_other.xml index d31f205efb2cdd3265fb3f42d9eddf3d6e4220a6..b97c4b0f48123381db93ca9413c049f97cc62ebf 100644 --- a/indra/newview/skins/default/xui/fr/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/fr/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Appeler" name="Call"/> <menu_item_call label="Inviter dans le groupe" name="Invite..."/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> <menu_item_call label="Ignorer" name="Avatar Mute"/> <menu_item_call label="Signaler" name="abuse"/> <menu_item_call label="Figer" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml index 1c768a078c82a3c5af2e1a3c1565e37cd38f000e..a4c1df8cee63edc28439ecf9c48aec9cee0e09e9 100644 --- a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Modifier ma tenue" name="Edit Outfit"/> <menu_item_call label="Modifier ma silhouette" name="Edit My Shape"/> <menu_item_call label="Hauteur de sustentation" name="Hover Height"/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> <menu_item_call label="Mes amis" name="Friends..."/> <menu_item_call label="Mes groupes" name="Groups..."/> <menu_item_call label="Mon profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 9b1f195391eba2626faf195f32b94969b09dd045..3c9f5c2aa904caf5023087976f9c80acf820ff74 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Ne pas déranger" name="Do Not Disturb"/> </menu> <menu_item_call label="Acheter des L$..." name="Buy and Sell L$"/> - <menu_item_call label="Boîte d'envoi vendeur..." name="MerchantOutbox"/> <menu_item_call label="Annonces de Place du marché..." name="MarketplaceListings"/> <menu_item_call label="Page d'accueil du compte..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=fr"/> @@ -421,6 +420,7 @@ <menu_item_check label="Désactiver LOD" name="Disable LOD"/> <menu_item_check label="Debogage Character Vis" name="Debug Character Vis"/> <menu_item_check label="Afficher le squelette de collision" name="Show Collision Skeleton"/> + <menu_item_check label="Voir les os" name="Show Bones"/> <menu_item_check label="Afficher la cible de l'avatar" name="Display Agent Target"/> <menu_item_call label="Dump Attachments" name="Dump Attachments"/> <menu_item_call label="Débogage des textures des avatars" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 080ea741c5ac0071a97f6ec845bf69530cf6b106..2310fc5611dd50a295d1d2995a470b310519f674 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -479,6 +479,9 @@ La limite de [MAX_ATTACHMENTS] objets joints a été dépassée. Veuillez commen <notification name="CannotWearInfoNotComplete"> Vous ne pouvez pas porter cet article car il n'a pas encore été chargé. Veuillez réessayer dans une minute. </notification> + <notification name="MustEnterPasswordToLogIn"> + Veuillez saisir votre mot de passe pour vous connecter. + </notification> <notification name="MustHaveAccountToLogIn"> Zut ! Vous avez oublié de fournir certaines informations. Vous devez saisir le nom d'utilisateur de votre avatar. @@ -547,6 +550,9 @@ Remarque : cela videra le cache. <notification name="ChangeConnectionPort"> Les paramètres du port prendront effet après le redémarrage de [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + Le changement de paramètre de débogage sera effectué au redémarrage de [APP_NAME]. + </notification> <notification name="ChangeSkin"> Le nouveau thème apparaîtra après le redémarrage de [APP_NAME]. </notification> @@ -1361,12 +1367,13 @@ Vous pouvez utiliser [SECOND_LIFE] normalement, les autres résidents vous voien <ignore name="ignore" text="Vos habits prennent du temps à télécharger"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité visuelle] est [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité de l'avatar] est [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="M'avertir si la complexité de l'avatar est trop élevée" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité visuelle] est [AGENT_COMPLEXITY]. + Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité de l'avatar] est [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> L'installation de [APP_NAME] est terminée. @@ -1483,6 +1490,10 @@ suivant votre vitesse de connexion. Etes-vous sûr(e) de vouloir figer le relief actuel, en faire le point central des limites d'élévation/abaissement de relief et la valeur par défaut du bouton Annuler modification ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Vous vous apprêtez à utiliser des valeurs plus élevées que les limites d'élévation supérieures. Continuer ? + <usetemplate canceltext="Ne pas demander" name="yesnocancelbuttons" notext="Annuler" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Vous ne pouvez pas autoriser plus de [MAX_AGENTS] résidents. </notification> @@ -1720,14 +1731,6 @@ Quitter le groupe ? Impossible de quitter le groupe. Vous ne pouvez pas quitter le groupe car vous en êtes le dernier propriétaire. Vous devez d'abord affecter le rôle de propriétaire à un autre membre. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - Impossible de quitter le groupe : [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Vous avez quitté le groupe [group_name]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> Souhaitez-vous vraiment éjecter tous les résidents de la grille ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="Éjecter tous les résidents"/> @@ -2400,6 +2403,10 @@ Voulez-vous désactiver Ne pas déranger avant de terminer cette transaction ? Êtes-vous certain de vouloir supprimer le contenu de votre corbeille de manière permanente ? <usetemplate ignoretext="Confirmer avant de vider la corbeille" name="okcancelignore" notext="Annuler" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Votre corbeille déborde. Cela risque de provoquer des problèmes lors de la connexion. + <usetemplate name="okcancelbuttons" notext="Je viderai la corbeille plus tard" yestext="Vider la corbeille"/> + </notification> <notification name="ConfirmClearBrowserCache"> Êtes-vous certain de vouloir supprimer l'historique de vos visites et recherches ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> @@ -2984,11 +2991,11 @@ Si vous restez dans cette région, vous serez déconnecté(e). Si vous restez dans cette région, vous serez déconnecté(e). </notification> <notification name="LoadWebPage"> - Charger la page Web [URL] ? + Charger la page Web [URL] ? [MESSAGE] -Venant de l'objet : <nolink>[OBJECTNAME]</nolink>, propriétaire : [NAME_SLURL] +Venant de l'objet : <nolink>[OBJECTNAME]</nolink>, propriétaire : [NAME_SLURL] <form name="form"> <button name="Gotopage" text="Charger"/> <button name="Cancel" text="Annuler"/> @@ -3257,11 +3264,15 @@ Elles vont être bloquées pendant quelques secondes pour votre sécurité. <notification name="AttachmentSaved"> L'élément joint a été sauvegardé. </notification> - <notification name="PresetNotSaved"> - Erreur d’enregistrement du préréglage [NAME]. + <notification name="AppearanceToXMLSaved"> + L'apparence a été enregistrée en XML vers [PATH] </notification> - <notification name="PresetNotDeleted"> - Erreur de suppression du préréglage [NAME]. + <notification name="AppearanceToXMLFailed"> + Échec d'enregistrement de l'apparence en XML. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +Erreur de suppression du préréglage [NAME]. </notification> <notification name="UnableToFindHelpTopic"> Impossible de trouver l'aide. @@ -4075,6 +4086,9 @@ Veuillez réessayer dans une minute. <notification name="CantAttachNotEnoughScriptResources"> Ressources de script insuffisantes pour attacher cet objet. </notification> + <notification name="IllegalAttachment"> + La pièce jointe a demandé un point non existant sur l'avatar. Il a été fixé sur la poitrine. + </notification> <notification name="CantDropItemTrialUser"> Vous ne pouvez pas déposer d'objets ici. Essayez la zone de période d'essai gratuite. </notification> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml index 901a92ed1bb4efbe2eb7ad4ce2c2f01f39d36116..85cd958f498625e2cb0ebb4bd6c5fc5e466a77b9 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Me prévenir : </text> - <check_box label="Quand je dépense ou que je reçois des L$" name="notify_money_change_checkbox"/> + <check_box label="Quand je dépense des L$" name="notify_money_spend_checkbox"/> <check_box label="Quand mes amis se connectent ou se déconnectent" name="friends_online_notify_checkbox"/> + <check_box label="Quand je reçois des L$" name="notify_money_received_checkbox"/> <text name="show_label"> Toujours afficher : </text> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml index 01d89f03f881b8b3ad7abe9d35fb07a37bbea497..2b1e613fe4709e36c9039b3ff157049a46782c2d 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Meilleure </text> + <slider label="Complexité max. de l'avatar :" name="IndirectMaxComplexity" tool_tip="Contrôle à quel moment un avatar complexe est représenté comme un « jelly baby »"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Effets atmosphériques" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modèle d’éclairage avancé" name="UseLightShaders"/> <button label="Enregistrer les paramètres comme préréglage..." name="PrefSaveButton"/> <button label="Charger un préréglage..." name="PrefLoadButton"/> + min_val="0,125" <button label="Supprimer un préréglage..." name="PrefDeleteButton"/> <button label="Réinitialiser les paramètres recommandés" name="Defaults"/> <button label="Paramètres avancés" name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/fr/panel_sound_devices.xml b/indra/newview/skins/default/xui/fr/panel_sound_devices.xml index 460b269f7ca4e9c47b57b259010698625f9aad41..720aaaf3e068ebc6a75996af6a968f542ce2606c 100644 --- a/indra/newview/skins/default/xui/fr/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/fr/panel_sound_devices.xml @@ -16,9 +16,9 @@ Sortie </text> <text name="My volume label"> - Mon volume : + Volume du micro : </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Régler le volume avec le curseur."/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Régler le volume du micro avec le curseur."/> <text name="wait_text"> Veuillez patienter </text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index ae091aba3933508a81bed0f20e2b6d4fff5f5d23..843467df96cebf0cf75dbd2b4ed33b387af763d5 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [Notes de version]] </string> + <string name="BuildConfig"> + Configuration de la construction [BUILD_CONFIG] + </string> <string name="AboutPosition"> Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL : <nolink>[SLURL]</nolink> @@ -72,6 +75,9 @@ Version serveur vocal : [VOICE_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> Erreur lors de la récupération de l'URL des notes de version du serveur. </string> + <string name="BuildConfiguration"> + Configuration de la construction + </string> <string name="ProgressRestoring"> Restauration... </string> @@ -1390,6 +1396,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="BodyPartsRightLeg"> Jambe droite </string> + <string name="BodyPartsEnhancedSkeleton"> + Squelette amélioré + </string> <string name="GraphicsQualityLow"> Faible </string> @@ -1838,6 +1847,51 @@ Veuillez réessayer de vous connecter dans une minute. <string name="Avatar Center"> Centre de l'avatar </string> + <string name="Left Ring Finger"> + Annulaire gauche + </string> + <string name="Right Ring Finger"> + Annulaire droit + </string> + <string name="Tail Base"> + Base de la queue + </string> + <string name="Tail Tip"> + Bout de la queue + </string> + <string name="Left Wing"> + Aile gauche + </string> + <string name="Right Wing"> + Aile droite + </string> + <string name="Jaw"> + Mâchoire + </string> + <string name="Alt Left Ear"> + Oreille gauche différente + </string> + <string name="Alt Right Ear"> + Oreille droite différente + </string> + <string name="Alt Left Eye"> + Å’il gauche différent + </string> + <string name="Alt Right Eye"> + Å’il droit différent + </string> + <string name="Tongue"> + Langue + </string> + <string name="Groin"> + Aine + </string> + <string name="Left Hind Foot"> + Pied arrière gauche + </string> + <string name="Right Hind Foot"> + Pied arrière droit + </string> <string name="Invalid Attachment"> Point d'attache non valide </string> @@ -2227,12 +2281,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ATTACH_BELLY"> Ventre </string> - <string name="ATTACH_RPEC"> - Pectoral droit - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Pectoral gauche </string> + <string name="ATTACH_RIGHT_PEC"> + Pectoral droit + </string> <string name="ATTACH_HUD_CENTER_2"> HUD centre 2 </string> @@ -2263,6 +2317,51 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ATTACH_AVATAR_CENTER"> Centre de l'avatar </string> + <string name="ATTACH_LHAND_RING1"> + Annulaire gauche + </string> + <string name="ATTACH_RHAND_RING1"> + Annulaire droit + </string> + <string name="ATTACH_TAIL_BASE"> + Base de la queue + </string> + <string name="ATTACH_TAIL_TIP"> + Bout de la queue + </string> + <string name="ATTACH_LWING"> + Aile gauche + </string> + <string name="ATTACH_RWING"> + Aile droite + </string> + <string name="ATTACH_FACE_JAW"> + Mâchoire + </string> + <string name="ATTACH_FACE_LEAR"> + Oreille gauche différente + </string> + <string name="ATTACH_FACE_REAR"> + Oreille droite différente + </string> + <string name="ATTACH_FACE_LEYE"> + Å’il gauche différent + </string> + <string name="ATTACH_FACE_REYE"> + Å’il droit différent + </string> + <string name="ATTACH_FACE_TONGUE"> + Langue + </string> + <string name="ATTACH_GROIN"> + Aine + </string> + <string name="ATTACH_HIND_LFOOT"> + Pied arrière gauche + </string> + <string name="ATTACH_HIND_RFOOT"> + Pied arrière droit + </string> <string name="CursorPos"> Ligne [LINE], colonne [COLUMN] </string> @@ -4252,6 +4351,12 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="OfflineStatus"> Hors ligne </string> + <string name="not_online_msg"> + Utilisateur non connecté - le message sera enregistré et livré plus tard. + </string> + <string name="not_online_inventory"> + Utilisateur non connecté - l'inventaire a été enregistré + </string> <string name="answered_call"> Votre appel a fait l'objet d'une réponse </string> diff --git a/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml index 5baba9fcedcf2526c24044838b43d952af45698d..056889126432a1aa8f18426a667d50759e0e36e1 100644 --- a/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complessità massima:" name="IndirectMaxComplexity" tool_tip="Definisce il punto in cui un avatar dall'aspetto complesso viene visualizzato come una forma senza dettagli"/> + <slider label="Complessità massima:" name="IndirectMaxComplexity" tool_tip="Definisce il punto in cui un avatar dall'aspetto complesso viene visualizzato come JellyDoll"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/it/menu_attachment_other.xml b/indra/newview/skins/default/xui/it/menu_attachment_other.xml index 60cdd2a91dc3f269dc3d0ac0ce3e1aa6efcbb11b..5c017a92b5cf2e10c16e37639e2d21391eda8a80 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Chiama" name="Call"/> <menu_item_call label="Invita al gruppo" name="Invite..."/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> <menu_item_call label="Blocca" name="Avatar Mute"/> <menu_item_call label="Segnala" name="abuse"/> <menu_item_call label="Congela" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/it/menu_attachment_self.xml b/indra/newview/skins/default/xui/it/menu_attachment_self.xml index 1539fbafa19a6c31148b4c4f389874d18f65f27b..b1ca55b093a35600f886c09d3b076afb3d524886 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Modifica il mio vestiario" name="Edit Outfit"/> <menu_item_call label="Modifica la figura corporea" name="Edit My Shape"/> <menu_item_call label="Altezza di volo" name="Hover Height"/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> <menu_item_call label="I miei amici..." name="Friends..."/> <menu_item_call label="I miei gruppi" name="Groups..."/> <menu_item_call label="Il mio profilo" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/it/menu_avatar_other.xml b/indra/newview/skins/default/xui/it/menu_avatar_other.xml index 7042e5294386c943c711ff09a35052d89828b5ce..12e808195e0ca2a66bd207c43e501e520239543f 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Chiama" name="Call"/> <menu_item_call label="Invita al gruppo" name="Invite..."/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> <menu_item_call label="Blocca" name="Avatar Mute"/> <menu_item_call label="Segnala" name="abuse"/> <menu_item_call label="Congela" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/it/menu_avatar_self.xml b/indra/newview/skins/default/xui/it/menu_avatar_self.xml index 0c9663fd4c6bbcf23944fabb261abca7b6c23363..e48449a04ca3339b40592c643259d5b0f7451e0a 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Modifica il mio vestiario" name="Edit Outfit"/> <menu_item_call label="Modifica la figura corporea" name="Edit My Shape"/> <menu_item_call label="Altezza di volo" name="Hover Height"/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> <menu_item_call label="I miei amici..." name="Friends..."/> <menu_item_call label="I miei gruppi" name="Groups..."/> <menu_item_call label="Il mio profilo" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index d52b022c496521f834fcb2ff620b1c8514dd10b1..90ea6012590ec07b6bef49f4968c0dad26d7336c 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Non disturbare" name="Do Not Disturb"/> </menu> <menu_item_call label="Acquista L$..." name="Buy and Sell L$"/> - <menu_item_call label="Casella venditore in uscita..." name="MerchantOutbox"/> <menu_item_call label="Annunci Marketplace..." name="MarketplaceListings"/> <menu_item_call label="Dashboard dell'account..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=it"/> @@ -368,6 +367,7 @@ <menu_item_check label="Informazioni sull'animazione" name="Animation Info"/> <menu_item_check label="Disabilita livello di dettaglio" name="Disable LOD"/> <menu_item_check label="Mostra schemi collisione" name="Show Collision Skeleton"/> + <menu_item_check label="Mostra ossa" name="Show Bones"/> <menu_item_check label="Mostra bersaglio" name="Display Agent Target"/> <menu_item_call label="Debug texture dell'avatar" name="Debug Avatar Textures"/> </menu> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 358f38a137285e0db96c20d5a2a329813ed7e8f2..3a29e4d32fcb2393338be81e4187bcf88cd20e62 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -480,6 +480,9 @@ Superato il limite di oggetti collegati [MAX_ATTACHMENTS]. Per favore prima stac <notification name="CannotWearInfoNotComplete"> Non puoi indossare quell'elemento perchè non è ancora stato caricato. Riprova fra un minuto. </notification> + <notification name="MustEnterPasswordToLogIn"> + Inserisci la tua password per accedere. + </notification> <notification name="MustHaveAccountToLogIn"> Spiacenti. Un campo è vuoto. Inserisci il Nome utente del tuo avatar. @@ -548,6 +551,9 @@ Nota: questa operazione cancellerà la cache. <notification name="ChangeConnectionPort"> Le impostazioni della porta avranno effetto dopo il riavvio di [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + La modifica della impostazione di debug avrà effetto dopo il riavvio di [APP_NAME]. + </notification> <notification name="ChangeSkin"> La nuova pelle comparirà dopo il riavvio di [APP_NAME]. </notification> @@ -1366,12 +1372,13 @@ Puoi comunque usare [SECOND_LIFE] normalmente e gli altri residenti ti vedranno <ignore name="ignore" text="Lo scaricamento sta richiedendo parecchio tempo"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - La tua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità visiva] è [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità del tuo avatar] è [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avvisami se la complessità del mio avatar è eccessiva" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - La tua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità visiva] è [AGENT_COMPLEXITY]. + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità del tuo avatar] è [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> L'installazione di [APP_NAME] è terminata. @@ -1486,6 +1493,10 @@ Sostituisci la texture [TEXTURE_NUM] con una a 24-bit 512x512 oppure con una imm Vuoi veramente impostare come base il terreno corrente, impostarlo come riferimento per i limiti dei rialzi/abbassamenti di tutto il territorio ed il suo valore impostato come base per lo strumento 'Ripristina'? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Stai per usare valori bassi maggiori dei valori alti di Intervalli altitudine. Vuoi procedere? + <usetemplate canceltext="Non chiedere" name="yesnocancelbuttons" notext="Annulla" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Puoi avere al massimo [MAX_AGENTS] residenti consentiti. </notification> @@ -1724,14 +1735,6 @@ Lasciare il gruppo? Impossibile abbandonare il gruppo. Non puoi abbandonare il gruppo perché sei l'ultimo proprietario del gruppo. Devi prima assegnare a un altro membro il ruolo di proprietario. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - Impossibile abbandonare il gruppo: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Hai abbandonato il gruppo [group_name]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> Vuoi veramente espellere tutti i residenti dalla griglia? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="Espelli tutti i residenti"/> @@ -2406,6 +2409,10 @@ Vuoi disattivare la modalità Non disturbare prima di completare questa transazi Vuoi veramente eliminare in modo permanente il contenuto del tuo Cestino? <usetemplate ignoretext="Conferma prima di svuotare la cartella del Cestino inventario" name="okcancelignore" notext="Annulla" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Il cestino è troppo pieno. Ciò potrebbe causare problemi durante l'accesso. + <usetemplate name="okcancelbuttons" notext="Svuota il cestino più tardi" yestext="Svuota il cestino adesso"/> + </notification> <notification name="ConfirmClearBrowserCache"> Vuoi veramente eliminare la cronologia viaggi, web e ricerche fatte? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> @@ -3262,11 +3269,15 @@ Per sicurezza, verranno bloccati per alcuni secondi. <notification name="AttachmentSaved"> L'elemento da collegare è stato salvato. </notification> - <notification name="PresetNotSaved"> - Errore durante il salvataggio del valore predefinito [NAME]. + <notification name="AppearanceToXMLSaved"> + L'aspetto è stato salvato in XML su [PATH] </notification> - <notification name="PresetNotDeleted"> - Errore durante l'eliminazione del valore predefinito [NAME]. + <notification name="AppearanceToXMLFailed"> + L'aspetto non è stato salvato in XML. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +Errore nella cancellazione del valore predefinito [NAME]. </notification> <notification name="UnableToFindHelpTopic"> Impossibile trovare l'argomento nell'aiuto per questo elemento. @@ -4081,6 +4092,9 @@ Riprova tra un minuto. <notification name="CantAttachNotEnoughScriptResources"> Risorse di script non sufficienti per collegare l'oggetto. </notification> + <notification name="IllegalAttachment"> + Il collegamento ha richiesto un punto sull'avatar che non esiste. È stato collegato al petto. + </notification> <notification name="CantDropItemTrialUser"> Non puoi lasciare oggetti qui, prova la zona Prova gratuita. </notification> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml index fd1fd57761bec461c12035b7a77918410f852cea..ca83490b02df02fbe9fa374300b9f85a909117fe 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Avvisami: </text> - <check_box label="Quando spendo o ottengo L$" name="notify_money_change_checkbox"/> + <check_box label="Quando spendo $" name="notify_money_spend_checkbox"/> <check_box label="Quando i miei amici entrano o escono da Second Life" name="friends_online_notify_checkbox"/> + <check_box label="Quando ottengo $" name="notify_money_received_checkbox"/> <text name="show_label"> Mostra sempre: </text> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml index a042c43431d310fd9999fb96c47aedf253763994..4fa1835b0eb322cecd52471a32ce441d2be39fac 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Migliore </text> + <slider label="Massima conplessità dell'avatar:" name="IndirectMaxComplexity" tool_tip="Definisce il punto in cui un avatar dall'aspetto complesso viene visualizzato come JellyDoll"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Shader atmosfera..." name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modello illuminazione avanzato" name="UseLightShaders"/> <button label="Salva impostazioni come valori predefiniti..." name="PrefSaveButton"/> <button label="Carica valore predefinito..." name="PrefLoadButton"/> + min_val="0.125" <button label="Elimina valore predefinito..." name="PrefDeleteButton"/> <button label="Ripristina impostazioni consigliate" name="Defaults"/> <button label="Impostazioni avanzate..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/it/panel_sound_devices.xml b/indra/newview/skins/default/xui/it/panel_sound_devices.xml index b1934fd515cd00ef6edec6fdd56d63c1477187d2..83df46f38167db4dcaac72d90f7f010a096ece36 100644 --- a/indra/newview/skins/default/xui/it/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/it/panel_sound_devices.xml @@ -16,9 +16,9 @@ Output </text> <text name="My volume label"> - Il mio volume: + Volume microfono: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia il volume utilizzando questa barra"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia il livello del microfono utilizzando questa barra"/> <text name="wait_text"> Attendi </text> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index effd6f50402b14c9e90ff90a619861d998f14d4a..bb2f221db9844893cfbdfee01098606c66f69d40 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -38,6 +38,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + Configurazione struttura [BUILD_CONFIG] + </string> <string name="AboutPosition"> Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -69,6 +72,9 @@ Versione server voce: [VOICE_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> Errore nel recupero URL note rilascio versione </string> + <string name="BuildConfiguration"> + Costruisci configurazione + </string> <string name="ProgressRestoring"> Ripristino in corso... </string> @@ -1381,6 +1387,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="BodyPartsRightLeg"> Gamba destra </string> + <string name="BodyPartsEnhancedSkeleton"> + Scheletro avanzato + </string> <string name="GraphicsQualityLow"> Basso </string> @@ -1823,6 +1832,51 @@ Prova ad accedere nuovamente tra un minuto. <string name="Avatar Center"> Centro avatar </string> + <string name="Left Ring Finger"> + Anulare sinistro + </string> + <string name="Right Ring Finger"> + Anulare destro + </string> + <string name="Tail Base"> + Base della coda + </string> + <string name="Tail Tip"> + Punta della coda + </string> + <string name="Left Wing"> + Ala sinistra + </string> + <string name="Right Wing"> + Ala destra + </string> + <string name="Jaw"> + Mandibola + </string> + <string name="Alt Left Ear"> + Altro orecchio sinistro + </string> + <string name="Alt Right Ear"> + Altro orecchio destro + </string> + <string name="Alt Left Eye"> + Altro occhio sinistro + </string> + <string name="Alt Right Eye"> + Altro occhio destro + </string> + <string name="Tongue"> + Lingua + </string> + <string name="Groin"> + Inguine + </string> + <string name="Left Hind Foot"> + Piede posteriore sinistro + </string> + <string name="Right Hind Foot"> + Piede posteriore destro + </string> <string name="Invalid Attachment"> Punto di collegamento non valido </string> @@ -2212,12 +2266,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="ATTACH_BELLY"> Addome </string> - <string name="ATTACH_RPEC"> - Petto destro - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Petto sinistro </string> + <string name="ATTACH_RIGHT_PEC"> + Petto destro + </string> <string name="ATTACH_HUD_CENTER_2"> HUD in centro 2 </string> @@ -2248,6 +2302,51 @@ Prova ad accedere nuovamente tra un minuto. <string name="ATTACH_AVATAR_CENTER"> Centro avatar </string> + <string name="ATTACH_LHAND_RING1"> + Anulare sinistro + </string> + <string name="ATTACH_RHAND_RING1"> + Anulare destro + </string> + <string name="ATTACH_TAIL_BASE"> + Base della coda + </string> + <string name="ATTACH_TAIL_TIP"> + Punta della coda + </string> + <string name="ATTACH_LWING"> + Ala sinistra + </string> + <string name="ATTACH_RWING"> + Ala destra + </string> + <string name="ATTACH_FACE_JAW"> + Mandibola + </string> + <string name="ATTACH_FACE_LEAR"> + Altro orecchio sinistro + </string> + <string name="ATTACH_FACE_REAR"> + Altro orecchio destro + </string> + <string name="ATTACH_FACE_LEYE"> + Altro occhio sinistro + </string> + <string name="ATTACH_FACE_REYE"> + Altro occhio destro + </string> + <string name="ATTACH_FACE_TONGUE"> + Lingua + </string> + <string name="ATTACH_GROIN"> + Inguine + </string> + <string name="ATTACH_HIND_LFOOT"> + Piede posteriore sinistro + </string> + <string name="ATTACH_HIND_RFOOT"> + Piede posteriore destro + </string> <string name="CursorPos"> Riga [LINE], Colonna [COLUMN] </string> @@ -4174,6 +4273,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="OfflineStatus"> Offline </string> + <string name="not_online_msg"> + Utente non online - il messaggio verrà memorizzato e inviato più tardi. + </string> + <string name="not_online_inventory"> + Utente non online - l'inventario è stato salvato + </string> <string name="answered_call"> Risposto alla chiamata </string> diff --git a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml index a95c45c275f2e051bb4e9c98a672d92dc1d4981d..db4e086c13a1db33eb2454e6b99f92a7567ec428 100644 --- a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> ã‚¢ãƒã‚¿ãƒ¼ </text> - <slider label="最大ã®è¤‡é›‘ã•ï¼š" name="IndirectMaxComplexity" tool_tip="ã©ã®æ™‚点ã§è¤‡é›‘ãªè¡¨ç¤ºã®ã‚¢ãƒã‚¿ãƒ¼ã‚’ベタ色ã®äººå½¢ã¨ã—ã¦è¡¨ç¤ºã™ã‚‹ã‹ã‚’管ç†ã—ã¾ã™"/> + <slider label="最大ã®è¤‡é›‘ã•ï¼š" name="IndirectMaxComplexity" tool_tip="ã©ã®ç‚¹ã§è¦–覚的ã«è¤‡é›‘ãªã‚¢ãƒã‚¿ãƒ¼ã‚’ JellyDoll ã¨ã—ã¦æãã‹ã‚’制御ã—ã¾ã™"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml index 7705dd909030cf66d5e7347f01cd5f3e55f41641..78c36a43927fe46d2d3194c89a07cccff82d92c6 100644 --- a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="コール" name="Call"/> <menu_item_call label="グループã«æ‹›å¾…" name="Invite..."/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> <menu_item_call label="ブãƒãƒƒã‚¯" name="Avatar Mute"/> <menu_item_call label="å ±å‘Š" name="abuse"/> <menu_item_call label="フリーズ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml index e7aa3cfc301783cae87fc22e340705322a306b84..ba46f91504b2931ae2501a9fb0c871375f54a4ca 100644 --- a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="アウトフィットã®ç·¨é›†" name="Edit Outfit"/> <menu_item_call label="シェイプã®ç·¨é›†" name="Edit My Shape"/> <menu_item_call label="ホãƒãƒ¼é«˜ã•" name="Hover Height"/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> <menu_item_call label="フレンド" name="Friends..."/> <menu_item_call label="グループ" name="Groups..."/> <menu_item_call label="プãƒãƒ•ã‚£ãƒ¼ãƒ«" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml index 482f2bdaa5f21e4923fb4bb16e07512502ed46c2..b7e05378663cbc52066ac30cf3feebb4a6742c25 100644 --- a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="コール" name="Call"/> <menu_item_call label="グループã«æ‹›å¾…" name="Invite..."/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> <menu_item_call label="ブãƒãƒƒã‚¯" name="Avatar Mute"/> <menu_item_call label="å ±å‘Š" name="abuse"/> <menu_item_call label="フリーズ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml index a14cfd58767bc4e9b6948725e85ae391149db52c..a3847ed555f5b6adb83bb74a5ef249771365b4d8 100644 --- a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="アウトフィットを編集" name="Edit Outfit"/> <menu_item_call label="シェイプを編集" name="Edit My Shape"/> <menu_item_call label="ホãƒãƒ¼é«˜ã•" name="Hover Height"/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> <menu_item_call label="フレンド" name="Friends..."/> <menu_item_call label="グループ" name="Groups..."/> <menu_item_call label="プãƒãƒ•ã‚£ãƒ¼ãƒ«" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 3c2e29486837521acd6d8074b99a54229b4a9dec..c2ae77bef21bb7918b8516a0b0921cc57a9c310f 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="ç€ä¿¡æ‹’å¦" name="Do Not Disturb"/> </menu> <menu_item_call label="L$ ã®è³¼å…¥..." name="Buy and Sell L$"/> - <menu_item_call label="マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹..." name="MerchantOutbox"/> <menu_item_call label="マーケティングプレイスã®ãƒªã‚¹ãƒˆ..." name="MarketplaceListings"/> <menu_item_call label="マイアカウント..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=ja"/> @@ -421,6 +420,7 @@ <menu_item_check label="LOD を無効ã«ã™ã‚‹" name="Disable LOD"/> <menu_item_check label="ã‚ャラクター Vis ã®ãƒ‡ãƒãƒƒã‚°" name="Debug Character Vis"/> <menu_item_check label="骨組ã¿ã®è¡çªåˆ¤å®šã‚’表示ã™ã‚‹" name="Show Collision Skeleton"/> + <menu_item_check label="骨を表示" name="Show Bones"/> <menu_item_check label="エージェントã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚’表示ã™ã‚‹" name="Display Agent Target"/> <menu_item_call label="アタッãƒãƒ¡ãƒ³ãƒˆã‚’ダンプ" name="Dump Attachments"/> <menu_item_call label="ã‚¢ãƒã‚¿ãƒ¼ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’デãƒãƒƒã‚°" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index a573e86e5f6e6f532f65dbb6a5f4276a7f60eaab..54e5f29621bc94cd533ea363da27514f8f6d1785 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -498,6 +498,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã <notification name="CannotWearInfoNotComplete"> ã¾ã èªã¿è¾¼ã¾ã‚Œã¦ã„ãªã„ãŸã‚ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ を装ç€ã§ãã¾ã›ã‚“。後ã§ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。 </notification> + <notification name="MustEnterPasswordToLogIn"> + ãƒã‚°ã‚¤ãƒ³ã™ã‚‹ãŸã‚ã«ãƒ‘スワードを入力ã—ã¦ãã ã•ã„ + </notification> <notification name="MustHaveAccountToLogIn"> 注æ„:記入æ¼ã‚Œã®ç®‡æ‰€ãŒã‚ã‚Šã¾ã™ã€‚ ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åを入力ã—ã¦ãã ã•ã„。 @@ -566,6 +569,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã <notification name="ChangeConnectionPort"> ãƒãƒ¼ãƒˆã®è¨å®šã¯ [APP_NAME] ã‚’å†èµ·å‹•å¾Œã«åæ˜ ã•ã‚Œã¾ã™ã€‚ </notification> + <notification name="ChangeDeferredDebugSetting"> + デãƒãƒƒã‚°è¨å®šã®å¤‰æ›´ã¯ [APP_NAME] ã‚’å†èµ·å‹•å¾Œã«åæ˜ ã•ã‚Œã¾ã™ã€‚ + </notification> <notification name="ChangeSkin"> æ–°ã—ã„スã‚ン㯠[APP_NAME] ã‚’å†èµ·å‹•å¾Œã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ </notification> @@ -1395,12 +1401,13 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries ã‚’å‚ç…§ã—ã¦ã <ignore name="ignore" text="衣類ãŒãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã•ã‚Œã‚‹ã¾ã§æ™‚é–“ãŒã‹ã‹ã£ã¦ã„ã‚‹ã¨ã"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - ã”使用㮠[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 表示ã®è¤‡é›‘ã•] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ + <notification name="AgentComplexityWithVisibility"> + ã‚ãªãŸã® [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ [OVERLIMIT_MSG] + <usetemplate ignoretext="ã‚¢ãƒã‚¿ãƒ¼ã®è¤‡é›‘度ãŒé«˜ã™ãŽã‚‹å ´åˆã¯è¦å‘Šã™ã‚‹" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - ã”使用㮠[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 表示ã®è¤‡é›‘ã•] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ + ã‚ãªãŸã® [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ </notification> <notification name="FirstRun"> [APP_NAME] ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã—ã¾ã—ãŸã€‚ @@ -1519,6 +1526,10 @@ SHA1 フィンガープリント: [MD5_DIGEST] æ“作を続行ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + 使用ã—よã†ã¨ã—ã¦ã„る隆起範囲ã®ä½Žã„値ã¯é«˜ã„値よりも大ãããªã£ã¦ã„ã¾ã™ã€‚ãã‚Œã§ã‚‚続ã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate canceltext="èžã‹ãªã„ã§ãã ã•ã„" name="yesnocancelbuttons" notext="å–り消ã—" yestext="Ok"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> 許å¯ä½äººã¯ [MAX_AGENTS] 人ã¾ã§ã§ã™ã€‚ </notification> @@ -1754,14 +1765,6 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ グループを抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。グループã®æœ€å¾Œã®ã‚ªãƒ¼ãƒŠãƒ¼ã§ã‚ã‚‹ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ—を抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。最åˆã«ã€åˆ¥ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’オーナーã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã¦ãã ã•ã„。 <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - グループを抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“: [reason]。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - グループ [group_name] を抜ã‘ã¾ã—ãŸã€‚ - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> 本当ã«ä½äººå…¨å“¡ã‚’グリッドã‹ã‚‰è¿½ã„出ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ã‚ャンセル" yestext="ä½äººå…¨å“¡ã‚’追ã„出ã™"/> @@ -2442,6 +2445,10 @@ Linden Lab ã”ã¿ç®±ã®ä¸èº«ã‚’ã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="インベントリã®ã”ã¿ç®±ãƒ•ã‚©ãƒ«ãƒ€ã‚’空ã«ã™ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + ゴミ箱ãŒã‚ãµã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ãƒã‚°ã‚¤ãƒ³æ™‚ã«å•é¡Œã‚’引ãèµ·ã“ã—ã¾ã™ã€‚ + <usetemplate name="okcancelbuttons" notext="後ã§ã‚´ãƒŸç®±ã‚’空ã«ã™ã‚‹" yestext="今ã™ãゴミ箱を空ã«ã™ã‚‹"/> + </notification> <notification name="ConfirmClearBrowserCache"> トラベルã€Webã€æ¤œç´¢ã®å±¥æ´ã‚’ã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ã‚ャンセル" yestext="OK"/> @@ -3032,7 +3039,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚» [MESSAGE] -é€ä¿¡å…ƒã®ã‚ªãƒ–ジェクト:<nolink>[OBJECTNAME]</nolink>ã€æ‰€æœ‰è€…:[NAME_SLURL] +é€ä¿¡å…ƒã®ã‚ªãƒ–ジェクト:<nolink>[OBJECTNAME]</nolink>ã€æ‰€æœ‰è€…:[NAME_SLURL] <form name="form"> <button name="Gotopage" text="ページã«ç§»å‹•"/> <button name="Cancel" text="å–り消ã—"/> @@ -3298,11 +3305,15 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="AttachmentSaved"> アタッãƒãƒ¡ãƒ³ãƒˆãŒä¿å˜ã•ã‚Œã¾ã—ãŸã€‚ </notification> - <notification name="PresetNotSaved"> - プリセット [NAME] ã®ä¿å˜ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + <notification name="AppearanceToXMLSaved"> + 外観㌠XML 㧠[PATH] ã«ä¿å˜ã•ã‚Œã¾ã—㟠</notification> - <notification name="PresetNotDeleted"> - プリセット [NAME] ã®å‰Šé™¤ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + <notification name="AppearanceToXMLFailed"> + 外観を XML ã«ä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +プリセット [NAME] ã®å‰Šé™¤ã‚¨ãƒ©ãƒ¼ã€‚ </notification> <notification name="UnableToFindHelpTopic"> ヘルプトピックãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ @@ -4111,6 +4122,9 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="CantAttachNotEnoughScriptResources"> オブジェクトã®ç€ç”¨ã«ä½¿ç”¨ã§ãるスクリプトリソースãŒè¶³ã‚Šã¾ã›ã‚“。 </notification> + <notification name="IllegalAttachment"> + 添付ファイルã¯ã‚¢ãƒã‚¿ãƒ¼ã®å˜åœ¨ã—ãªã„点をè¦æ±‚ã—ã¾ã—ãŸã€‚代ã‚ã‚Šã«èƒ¸ã«æ·»ä»˜ã•ã‚Œã¦ã„ã¾ã—ãŸã€‚ + </notification> <notification name="CantDropItemTrialUser"> オブジェクトをã“ã“ã«ãƒ‰ãƒãƒƒãƒ—ã§ãã¾ã›ã‚“ã€‚ãƒ•ãƒªãƒ¼ãƒˆãƒ©ã‚¤ã‚¢ãƒ«é ˜åŸŸã‚’ãŠè©¦ã—ãã ã•ã„。 </notification> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml index 7fd2e316982ffc091db75c11db006de4f13e57b5..4c2906cc1870962c7d7f5c29202c24f775dcfd59 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> 知らã›ã‚‹ï¼š </text> - <check_box label="リンデンドルを使用・å—ã‘å–ã‚‹ã¨ã" name="notify_money_change_checkbox"/> + <check_box label="L$ を使用ã™ã‚‹å ´åˆ" name="notify_money_spend_checkbox"/> <check_box label="フレンドãŒãƒã‚°ã‚¤ãƒ³ãƒ»ãƒã‚°ã‚¢ã‚¦ãƒˆã™ã‚‹ã¨ã" name="friends_online_notify_checkbox"/> + <check_box label="L$ を手ã«å…¥ã‚Œã‚‹å ´åˆ" name="notify_money_received_checkbox"/> <text name="show_label" width="300"> 常ã«è¡¨ç¤ºã™ã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ï¼š </text> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml index 8fbe9b56b9cca1b153d3d3406fb8716cecb861f5..61d914135db7efe41dab20388b35ff9013963191 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> é…ã„ </text> + <slider label="ã‚¢ãƒã‚¿ãƒ¼ã®æœ€å¤§è¤‡é›‘度:" name="IndirectMaxComplexity" tool_tip="ã©ã®ç‚¹ã§è¦–覚的ã«è¤‡é›‘ãªã‚¢ãƒã‚¿ãƒ¼ã‚’ JellyDoll ã¨ã—ã¦æãã‹ã‚’制御ã—ã¾ã™"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="周囲 (大気) シェーダー" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="高度ãªãƒ©ã‚¤ãƒ†ã‚£ãƒ³ã‚°ãƒ¢ãƒ‡ãƒ«" name="UseLightShaders"/> <button label="è¨å®šã‚’プリセットã¨ã—ã¦ä¿å˜..." name="PrefSaveButton"/> <button label="プリセットをãƒãƒ¼ãƒ‰..." name="PrefLoadButton"/> + min_val="0.125" <button label="事å‰è¨å®šã‚’削除..." name="PrefDeleteButton"/> <button label="推奨è¨å®šã«ãƒªã‚»ãƒƒãƒˆ" name="Defaults"/> <button label="詳細è¨å®š..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/ja/panel_sound_devices.xml b/indra/newview/skins/default/xui/ja/panel_sound_devices.xml index 08245042350e5baf1e747e99d2474d33d1534db2..d57e6c796c1755a3c7ed86da5bbcd782e2626e69 100644 --- a/indra/newview/skins/default/xui/ja/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/ja/panel_sound_devices.xml @@ -16,9 +16,9 @@ 出力 </text> <text name="My volume label"> - ç§ã®éŸ³é‡ï¼š + マイク音é‡: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="スライダーを使ã£ã¦éŸ³é‡ã‚’調節ã—ã¾ã™"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="スライダーを使ã£ã¦ãƒžã‚¤ã‚¯ãƒ¬ãƒ™ãƒ«ã‚’調節ã—ã¾ã™"/> <text name="wait_text"> ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。 </text> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 1ad977fe88550f4721af9115726165654148a45e..904ce3880a4475f9497c0e4cd9dffcf65d03e786 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -38,7 +38,11 @@ グラフィックをåˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚グラフィックドライãƒã‚’æ›´æ–°ã—ã¦ãã ã•ã„。 </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL])[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + ãƒ“ãƒ«ãƒ‰æ§‹æˆ [BUILD_CONFIG] </string> <string name="AboutPosition"> ã‚ãªãŸã®ç¾åœ¨åœ°ã¯ã€[POSITION_LOCAL_0,number,1]ã€[POSITION_LOCAL_1,number,1]ã€[POSITION_LOCAL_2,number,1] ã® [REGION] ã§ã™ã€‚ä½ç½®ã¯ <nolink>[HOSTNAME]</nolink> ã§ã™ã€‚([HOSTIP]) @@ -62,8 +66,8 @@ OS ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[OS_VERSION] J2C デコーダãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[J2C_VERSION] オーディオドライãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[AUDIO_DRIVER_VERSION] -LLCEFLib/CEF ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [LLCEFLIB_VERSION] -ボイスサーãƒãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [VOICE_VERSION] +LLCEFLib/CEF ãƒãƒ¼ã‚¸ãƒ§ãƒ³: [LLCEFLIB_VERSION] +ボイスサーãƒãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³:[VOICE_VERSION] </string> <string name="AboutTraffic"> パケットãƒã‚¹ï¼š[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -71,6 +75,9 @@ LLCEFLib/CEF ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [LLCEFLIB_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> サーãƒãƒ¼ã®ãƒªãƒªãƒ¼ã‚¹ãƒŽãƒ¼ãƒˆã® URL ã‚’å–å¾—ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ </string> + <string name="BuildConfiguration"> + ãƒ“ãƒ«ãƒ‰æ§‹æˆ + </string> <string name="ProgressRestoring"> 復元ä¸ã§ã™... </string> @@ -1389,6 +1396,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="BodyPartsRightLeg"> å³è„š </string> + <string name="BodyPartsEnhancedSkeleton"> + 拡張スケルトン + </string> <string name="GraphicsQualityLow"> 低 </string> @@ -1837,6 +1847,51 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="Avatar Center"> ã‚¢ãƒã‚¿ãƒ¼ã®ä¸å¤® </string> + <string name="Left Ring Finger"> + 左薬指 + </string> + <string name="Right Ring Finger"> + å³è–¬æŒ‡ + </string> + <string name="Tail Base"> + ã—ã£ã½ã®ãƒ™ãƒ¼ã‚¹ + </string> + <string name="Tail Tip"> + ã—ã£ã½ã®å…ˆ + </string> + <string name="Left Wing"> + å·¦ã®ç¿¼ + </string> + <string name="Right Wing"> + å³ã®ç¿¼ + </string> + <string name="Jaw"> + é¡Ž + </string> + <string name="Alt Left Ear"> + 代ã‚ã‚Šã®å·¦è€³ + </string> + <string name="Alt Right Ear"> + 代ã‚ã‚Šã®å³è€³ + </string> + <string name="Alt Left Eye"> + 代ã‚ã‚Šã®å·¦ç›® + </string> + <string name="Alt Right Eye"> + 代ã‚ã‚Šã®å³ç›® + </string> + <string name="Tongue"> + 舌 + </string> + <string name="Groin"> + è„šã®ä»˜ã‘æ ¹ + </string> + <string name="Left Hind Foot"> + 左後足 + </string> + <string name="Right Hind Foot"> + å³å¾Œè¶³ + </string> <string name="Invalid Attachment"> 装ç€å…ˆãŒæ£ã—ãã‚ã‚Šã¾ã›ã‚“ </string> @@ -2226,12 +2281,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ATTACH_BELLY"> ãŠè…¹ </string> - <string name="ATTACH_RPEC"> - å³èƒ¸ç‹ - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> å·¦èƒ¸ç‹ </string> + <string name="ATTACH_RIGHT_PEC"> + å³èƒ¸ç‹ + </string> <string name="ATTACH_HUD_CENTER_2"> HUD(ä¸å¤® 2) </string> @@ -2262,6 +2317,51 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ATTACH_AVATAR_CENTER"> ã‚¢ãƒã‚¿ãƒ¼ã®ä¸å¤® </string> + <string name="ATTACH_LHAND_RING1"> + 左薬指 + </string> + <string name="ATTACH_RHAND_RING1"> + å³è–¬æŒ‡ + </string> + <string name="ATTACH_TAIL_BASE"> + ã—ã£ã½ã®ãƒ™ãƒ¼ã‚¹ + </string> + <string name="ATTACH_TAIL_TIP"> + ã—ã£ã½ã®å…ˆ + </string> + <string name="ATTACH_LWING"> + å·¦ã®ç¿¼ + </string> + <string name="ATTACH_RWING"> + å³ã®ç¿¼ + </string> + <string name="ATTACH_FACE_JAW"> + é¡Ž + </string> + <string name="ATTACH_FACE_LEAR"> + 代ã‚ã‚Šã®å·¦è€³ + </string> + <string name="ATTACH_FACE_REAR"> + 代ã‚ã‚Šã®å³è€³ + </string> + <string name="ATTACH_FACE_LEYE"> + 代ã‚ã‚Šã®å·¦ç›® + </string> + <string name="ATTACH_FACE_REYE"> + 代ã‚ã‚Šã®å³ç›® + </string> + <string name="ATTACH_FACE_TONGUE"> + 舌 + </string> + <string name="ATTACH_GROIN"> + è„šã®ä»˜ã‘æ ¹ + </string> + <string name="ATTACH_HIND_LFOOT"> + 左後足 + </string> + <string name="ATTACH_HIND_RFOOT"> + å³å¾Œè¶³ + </string> <string name="CursorPos"> [LINE] 行目ã€[COLUMN] 列目 </string> @@ -4251,6 +4351,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="OfflineStatus"> オフライン </string> + <string name="not_online_msg"> + ユーザーãŒã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã‚ã‚Šã¾ã›ã‚“ - メッセージã¯ä¿å˜ã•ã‚Œã€å¾Œã§é…ä¿¡ã•ã‚Œã¾ã™ã€‚ + </string> + <string name="not_online_inventory"> + ユーザーãŒã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã‚ã‚Šã¾ã›ã‚“ - インベントリãŒä¿å˜ã•ã‚Œã¾ã—ãŸã€‚ + </string> <string name="answered_call"> 相手ãŒã‚³ãƒ¼ãƒ«ã‚’å—ã‘ã¾ã—㟠</string> diff --git a/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml index c5e19b2281c47fd1e0c3d8c6d600a450f5f5a811..6fa25262ea858c4ced4751a5c401603d51cda4e3 100644 --- a/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complexidade máxima:" name="IndirectMaxComplexity" tool_tip="Controla o ponto no qual um avatar visualmente complexo é desenhado como avatar de cor sólida"/> + <slider label="Complexidade máxima:" name="IndirectMaxComplexity" tool_tip="Controla o ponto no qual um avatar visualmente complexo é desenhado como uma JellyDoll"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_other.xml b/indra/newview/skins/default/xui/pt/menu_attachment_other.xml index 031f6b605aa560b4fd8b8e0c65911659fbadd3a6..760197cfb999ea33d1a866fb3c8614f41b808090 100644 --- a/indra/newview/skins/default/xui/pt/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/pt/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Ligar" name="Call"/> <menu_item_call label="Convidar para entrar no grupo" name="Invite..."/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> <menu_item_call label="Bloquear" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml index ac7942211039fee43bb438257eae526bb3a64c49..766c8b975499ca9396f1a87b864ae41e8c51b633 100644 --- a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Editar meu look" name="Edit Outfit"/> <menu_item_call label="Editar meu corpo" name="Edit My Shape"/> <menu_item_call label="Altura de foco" name="Hover Height"/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> <menu_item_call label="Meus amigos" name="Friends..."/> <menu_item_call label="Meus grupos" name="Groups..."/> <menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_other.xml b/indra/newview/skins/default/xui/pt/menu_avatar_other.xml index e32f9059f52cffa8980aa3053d9226ab21a5e9a7..170525cbe6d935c2d6456760d852c72a4bfba160 100644 --- a/indra/newview/skins/default/xui/pt/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/pt/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Ligar" name="Call"/> <menu_item_call label="Convidar para entrar no grupo" name="Invite..."/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> <menu_item_call label="Bloquear" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml index a0ac71e0186d56d1e69c11cee2087f9159dd7c96..e826a57b46d9e5b10ad4745e67bb16ff64694656 100644 --- a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Editar meu look" name="Edit Outfit"/> <menu_item_call label="Editar meu corpo" name="Edit My Shape"/> <menu_item_call label="Altura de foco" name="Hover Height"/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> <menu_item_call label="Meus amigos" name="Friends..."/> <menu_item_call label="Meus grupos" name="Groups..."/> <menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 2df78c6287bb6fdd2118d3a1c6a7533fff2977cb..7bdcb74a54cb89b9c6fd7fdbdbd29b7d5d1a260f 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Não perturbe" name="Do Not Disturb"/> </menu> <menu_item_call label="Comprar L$..." name="Buy and Sell L$"/> - <menu_item_call label="Caixa de saÃda do lojista..." name="MerchantOutbox"/> <menu_item_call label="Listagens do Marketplace..." name="MarketplaceListings"/> <menu_item_call label="Painel da conta..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=pt"/> @@ -368,6 +367,7 @@ <menu_item_check label="Dados da animação" name="Animation Info"/> <menu_item_check label="Disable Level Of Detail" name="Disable LOD"/> <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> + <menu_item_check label="Exibir ossos" name="Show Bones"/> <menu_item_check label="Display Agent Target" name="Display Agent Target"/> <menu_item_call label="Depurar texturas do avatar" name="Debug Avatar Textures"/> </menu> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index cf7400117d6a7c1ef181cad15293ba0eb521f4e4..bb428ad5a553720870e5f7ced8c301ded21890e4 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -477,6 +477,9 @@ Ele ultrapassa o limite de anexos, de [MAX_ATTACHMENTS] objetos. Remova um objet <notification name="CannotWearInfoNotComplete"> Você não pode vestir este item porque ele ainda não carregou. Tente novamente em um minuto. </notification> + <notification name="MustEnterPasswordToLogIn"> + Informe sua senha para fazer o login. + </notification> <notification name="MustHaveAccountToLogIn"> Opa! Alguma coisa ficou em branco. Digite o nome de usuário de seu avatar. @@ -545,6 +548,9 @@ Nota: Este procedimento limpa o cache. <notification name="ChangeConnectionPort"> Reinicie o [APP_NAME] para ativar a reconfiguração da porta. </notification> + <notification name="ChangeDeferredDebugSetting"> + Essa alteração nas configurações de depuração será aplicada depois que você reiniciar o [APP_NAME]. + </notification> <notification name="ChangeSkin"> Reinicie o [APP_NAME] para ativar a pele nova. </notification> @@ -1359,12 +1365,13 @@ Enquando isso, use o [SECOND_LIFE] normalmente. Seu visual será exibido correta <ignore name="ignore" text="A roupa está demorando para chegar"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexidade visual] é [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] é [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avise-me se a complexidade do meu avatar for muito alta" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexidade visual] é [AGENT_COMPLEXITY]. + Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] é [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> A instalação do [APP_NAME] está pronta. @@ -1478,6 +1485,10 @@ Substituir textura [TEXTURE_NUM], com uma imagem de 24-bit 512x512 ou menor e em Você realmente deseja nivelar o terreno selecionado a partir do centro elevando/reduzindo os limites e o padrão para a ferramenta ´Reverter´? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Executar"/> </notification> + <notification name="ConfirmTextureHeights"> + Você está prestes a usar valores baixos maiores que os valores altos para os intervalos de elevação. Deseja prosseguir? + <usetemplate canceltext="Não perguntar" name="yesnocancelbuttons" notext="Cancelar" yestext="Ok"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Você pode ter somente [MAX_AGENTS] residentes permitidos. </notification> @@ -1714,14 +1725,6 @@ Se você estiver muito ansioso para experimentar os novos recursos e correções Não foi possÃvel deixar o grupo. Você não pode deixar o grupo pois é o último proprietário dele. Primeiramente, atribua outro membro à função de proprietário. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - Não foi possÃvel deixar o grupo: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Você deixou o grupo [group_name]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> Tem CERTEZA de que deseja expulsar todos os residentes do grid? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Chutar todos"/> @@ -2393,6 +2396,10 @@ Deseja desativar o Não perturbe antes de concluir esta transação? Tem certeza de que deseja excluir o conteúdo da Lixeira? Para sempre? <usetemplate ignoretext="Confirmar antes de esvaziar a pasta Lixeira" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> + <notification name="TrashIsFull"> + Sua lixeira está transbordando. Isso pode causar problemas no logon. + <usetemplate name="okcancelbuttons" notext="Esvaziarei a lixeira mais tarde" yestext="Esvaziar lixeira agora"/> + </notification> <notification name="ConfirmClearBrowserCache"> Tem certeza de que quer apagar todo o histórico de viagens, web e buscas? <usetemplate name="okcancelbuttons" notext="Não" yestext="OK"/> @@ -2977,7 +2984,7 @@ Se permanecer aqui, você será desconectado. [MESSAGE] -Do objeto: <nolink>[OBJECTNAME]</nolink>, de: [NAME_SLURL] +Do objeto: <nolink>[OBJECTNAME]</nolink>, proprietário: [NAME_SLURL] <form name="form"> <button name="Gotopage" text="Carregar"/> <button name="Cancel" text="Cancelar"/> @@ -3246,11 +3253,15 @@ Para sua segurança, os SLurls serão bloqueados por alguns instantes. <notification name="AttachmentSaved"> Anexo salvo. </notification> - <notification name="PresetNotSaved"> - Erro ao salvar predefinição [NAME]. + <notification name="AppearanceToXMLSaved"> + A aparência foi salva como XML em [PATH] </notification> - <notification name="PresetNotDeleted"> - Erro ao excluir a predefinição [NAME]. + <notification name="AppearanceToXMLFailed"> + Falha ao salvar a aparência como XML. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +Erro ao excluir a predefinição [NAME]. </notification> <notification name="UnableToFindHelpTopic"> Nenhum tópico de ajuda foi encontrado com relação a este elemento. @@ -4063,6 +4074,9 @@ Tente novamente em instantes. <notification name="CantAttachNotEnoughScriptResources"> Não há recursos de script disponÃveis suficientes para anexar objeto! </notification> + <notification name="IllegalAttachment"> + O anexo solicitou um ponto não existente no avatar. Ele foi anexado ao peito. + </notification> <notification name="CantDropItemTrialUser"> Não é possÃvel largar objetos aqui. Tente a área de Avaliação grátis. </notification> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml index 2ffe720ccf863256a3572ef029d95f66883c560d..c865de0d08611d781c047c68e84bad7aa9473abb 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Avisar: </text> - <check_box label="Quando eu gasto ou recebo L$" name="notify_money_change_checkbox"/> + <check_box label="Quando eu gastar L$" name="notify_money_spend_checkbox"/> <check_box label="Quando meus amigos entram e saem" name="friends_online_notify_checkbox"/> + <check_box label="Quando eu receber L$" name="notify_money_received_checkbox"/> <text name="show_label"> Mostrar sempre: </text> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index 4d3fb89b37ff9e946a5fff0d3219143025462ef8..fa17a4ff110e9907183060dfbb890bfd2cbf2474 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -25,10 +25,15 @@ rápido <text name="BetterText"> Melhor </text> + <slider label="Complexidade máxima do avatar:" name="IndirectMaxComplexity" tool_tip="Controla o ponto no qual um avatar visualmente complexo é desenhado como uma JellyDoll"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Tonalidades atmosféricas" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modelo avançado de luzes" name="UseLightShaders"/> <button label="Salvar configurações como predefinição..." name="PrefSaveButton"/> <button label="Carregar predefinição..." name="PrefLoadButton"/> + min_val="0.125" <button label="Excluir predefinição..." name="PrefDeleteButton"/> <button label="Redefinir para configurações recomendadas" left="110" name="Defaults"/> <button label="Configurações avançadas..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/pt/panel_sound_devices.xml b/indra/newview/skins/default/xui/pt/panel_sound_devices.xml index 66db89f48f4b0391bbce295d0a65721c275668bf..97d6c0ef3639604d806f5b22eeb2656f59ab8c35 100644 --- a/indra/newview/skins/default/xui/pt/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/pt/panel_sound_devices.xml @@ -16,9 +16,9 @@ SaÃda </text> <text name="My volume label"> - Meu volume: + Volume do microfone: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Mude o volume usando o controle deslizante"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Mude o volume do microfone usando o controle deslizante"/> <text name="wait_text"> Aguarde </text> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 50bb9b7e669891b0a0c99c90a7ad87706d6d2867..b3cb50a01e520698d5724ef19b765e88bf91c034 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -30,7 +30,10 @@ </string> <string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) -[[VIEWER_RELEASE_NOTES_URL] [Notas da versão]] +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Configuração do corpo [BUILD_CONFIG] </string> <string name="AboutPosition"> Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink> ([HOSTIP]) @@ -63,6 +66,9 @@ Versão do servidor de voz: [VOICE_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> Erro ao obter URL de notas de versão do servidor. </string> + <string name="BuildConfiguration"> + Configuração do corpo + </string> <string name="ProgressRestoring"> Restaurando... </string> @@ -1336,6 +1342,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="BodyPartsRightLeg"> Perna direita </string> + <string name="BodyPartsEnhancedSkeleton"> + Esqueleto aprimorado + </string> <string name="GraphicsQualityLow"> Baixo </string> @@ -1778,6 +1787,51 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="Avatar Center"> Centro do avatar </string> + <string name="Left Ring Finger"> + Anelar esquerdo + </string> + <string name="Right Ring Finger"> + Anelar direito + </string> + <string name="Tail Base"> + Base do rabo + </string> + <string name="Tail Tip"> + Ponta do rabo + </string> + <string name="Left Wing"> + Asa esquerda + </string> + <string name="Right Wing"> + Asa direita + </string> + <string name="Jaw"> + Maxilar + </string> + <string name="Alt Left Ear"> + Orelha esquerda alt. + </string> + <string name="Alt Right Ear"> + Orelha direita alt. + </string> + <string name="Alt Left Eye"> + Olho esquerdo alt. + </string> + <string name="Alt Right Eye"> + Olho direito alt. + </string> + <string name="Tongue"> + LÃngua + </string> + <string name="Groin"> + Virilha + </string> + <string name="Left Hind Foot"> + Pata esq. traseira + </string> + <string name="Right Hind Foot"> + Pata dir. traseira + </string> <string name="Invalid Attachment"> Ponto de encaixe inválido </string> @@ -2167,12 +2221,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="ATTACH_BELLY"> Barriga </string> - <string name="ATTACH_RPEC"> - Peitorais D - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Peitorais E </string> + <string name="ATTACH_RIGHT_PEC"> + Peitorais D + </string> <string name="ATTACH_HUD_CENTER_2"> HUD Central 2 </string> @@ -2203,6 +2257,51 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="ATTACH_AVATAR_CENTER"> Centro do avatar </string> + <string name="ATTACH_LHAND_RING1"> + Anelar esquerdo + </string> + <string name="ATTACH_RHAND_RING1"> + Anelar direito + </string> + <string name="ATTACH_TAIL_BASE"> + Base do rabo + </string> + <string name="ATTACH_TAIL_TIP"> + Ponta do rabo + </string> + <string name="ATTACH_LWING"> + Asa esquerda + </string> + <string name="ATTACH_RWING"> + Asa direita + </string> + <string name="ATTACH_FACE_JAW"> + Maxilar + </string> + <string name="ATTACH_FACE_LEAR"> + Orelha esquerda alt. + </string> + <string name="ATTACH_FACE_REAR"> + Orelha direita alt. + </string> + <string name="ATTACH_FACE_LEYE"> + Olho esquerdo alt. + </string> + <string name="ATTACH_FACE_REYE"> + Olho direito alt. + </string> + <string name="ATTACH_FACE_TONGUE"> + LÃngua + </string> + <string name="ATTACH_GROIN"> + Virilha + </string> + <string name="ATTACH_HIND_LFOOT"> + Pata esq. traseira + </string> + <string name="ATTACH_HIND_RFOOT"> + Pata dir. traseira + </string> <string name="CursorPos"> Linha [LINE], Coluna [COLUMN] </string> @@ -4128,6 +4227,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="OfflineStatus"> Desconectado </string> + <string name="not_online_msg"> + O usuário não está online. As mensagens serão armazenadas e enviadas mais tarde. + </string> + <string name="not_online_inventory"> + O usuário não está online. O inventário foi salvo. + </string> <string name="answered_call"> Ligação atendida </string> diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_other.xml b/indra/newview/skins/default/xui/ru/menu_attachment_other.xml index bd1ed8d1fa2d4f96faf6ff9b9b2334a4cd62cb6b..b7ffb0e9fc77f69f4ba5488477e7667e045fdb67 100644 --- a/indra/newview/skins/default/xui/ru/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/ru/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Звонок" name="Call"/> <menu_item_call label="ПриглаÑить в группу" name="Invite..."/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> <menu_item_call label="Заблокировать" name="Avatar Mute"/> <menu_item_call label="ПожаловатьÑÑ" name="abuse"/> <menu_item_call label="Заморозить" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml index 033d36484b2e3fb091dc0a77c09a45b1e35ab9ee..eb38371e2853aae59f7078f317c6f3f5cbfea3ad 100644 --- a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Изменить коÑтюм" name="Edit Outfit"/> <menu_item_call label="Изменить фигуру" name="Edit My Shape"/> <menu_item_call label="Ð’Ñ‹Ñота парениÑ" name="Hover Height"/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> <menu_item_call label="Мои друзьÑ" name="Friends..."/> <menu_item_call label="Мои группы" name="Groups..."/> <menu_item_call label="Мой профиль" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_other.xml b/indra/newview/skins/default/xui/ru/menu_avatar_other.xml index 74f1a396581b5f21de8c1c7e6b96b47973c387d7..cffb4bbe7b624e729a01070856c5989276b8a749 100644 --- a/indra/newview/skins/default/xui/ru/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/ru/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Звонок" name="Call"/> <menu_item_call label="ПриглаÑить в группу" name="Invite..."/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> <menu_item_call label="Заблокировать" name="Avatar Mute"/> <menu_item_call label="ПожаловатьÑÑ" name="abuse"/> <menu_item_call label="Заморозить" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml index 8feaa3b99a258e01fe389091db9c5c0f3b02367d..97e2a8b295f4539066fe5889a2ab6d060b739cc2 100644 --- a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Изменить коÑтюм" name="Edit Outfit"/> <menu_item_call label="Изменить фигуру" name="Edit My Shape"/> <menu_item_call label="Ð’Ñ‹Ñота парениÑ" name="Hover Height"/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> <menu_item_call label="Мои друзьÑ" name="Friends..."/> <menu_item_call label="Мои группы" name="Groups..."/> <menu_item_call label="Мой профиль" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index 2044844c588b56aa8f1d56d7aee76919ce835f50..6158363e5d53dca39d49fab06e5c75855a3dd2dc 100644 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Ðе беÑпокоить" name="Do Not Disturb"/> </menu> <menu_item_call label="Купить L$..." name="Buy and Sell L$"/> - <menu_item_call label="Торговые иÑходÑщие..." name="MerchantOutbox"/> <menu_item_call label="СпиÑки товаров торгового центра..." name="MarketplaceListings"/> <menu_item_call label="Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ аккаунта..." name="Manage My Account"/> <menu_item_call label="ÐаÑтройки..." name="Preferences"/> @@ -418,6 +417,7 @@ <menu_item_check label="Отключить детализацию" name="Disable LOD"/> <menu_item_check label="Отладка видимоÑти перÑонажа" name="Debug Character Vis"/> <menu_item_check label="Показать Ñкелет" name="Show Collision Skeleton"/> + <menu_item_check label="Показать коÑти" name="Show Bones"/> <menu_item_check label="Отобразить дейÑтвие агента" name="Display Agent Target"/> <menu_item_call label="Вывод приÑоединений" name="Dump Attachments"/> <menu_item_call label="Отладка текÑтур аватара" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index fabc0645251eeff2b3608312ec99bb7a18b6545b..5e7c2ed7d063485ad53ae1b86d9e958a438b2cf6 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -480,6 +480,9 @@ <notification name="CannotWearInfoNotComplete"> ÐÐµÐ»ÑŒÐ·Ñ Ð½Ð°Ð´ÐµÑ‚ÑŒ Ñту вещь, так как она еще не загружена. Повторите попытку через минуту. </notification> + <notification name="MustEnterPasswordToLogIn"> + Введите пароль Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в мир. + </notification> <notification name="MustHaveAccountToLogIn"> Ðй-Ñй-Ñй! Что-то оÑталоÑÑŒ незаполненным. Ðеобходимо ввеÑти Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ аватара. @@ -548,6 +551,9 @@ <notification name="ChangeConnectionPort"> ÐаÑтройки порта начнут дейÑтвовать поÑле перезапуÑка [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + Ðта наÑтройка отладки вÑтупит в Ñилу поÑле перезапуÑка [APP_NAME]. + </notification> <notification name="ChangeSkin"> ÐÐ¾Ð²Ð°Ñ ÐºÐ¾Ð¶Ð° будет видна поÑле перезапуÑка [APP_NAME]. </notification> @@ -1366,12 +1372,13 @@ <ignore name="ignore" text="Загрузка одежды занимает значительное времÑ"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ ÑложноÑÑ‚ÑŒ]: [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 ÑложноÑÑ‚ÑŒ аватара]: [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Предупреждать о превышении ÑложноÑти аватара" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ ÑложноÑÑ‚ÑŒ]: [AGENT_COMPLEXITY]. + Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 ÑложноÑÑ‚ÑŒ аватара]: [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> УÑтановка [APP_NAME] завершена. @@ -1486,6 +1493,10 @@ Ð’Ñ‹ дейÑтвительно хотите зафикÑировать текущий ландшафт, Ñделать его выÑоту Ñредней точкой Ð´Ð»Ñ Ð²ÐµÑ€Ñ…Ð½ÐµÐ¹ и нижней точек ландшафта и принÑÑ‚ÑŒ по умолчанию Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ «Вернуть»? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Ð’Ñ‹ ÑобираетеÑÑŒ иÑпользовать минимальные значениÑ, которые больше, чем макÑимальные Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° выÑот. Ðачать? + <usetemplate canceltext="Ðе Ñпрашивать" name="yesnocancelbuttons" notext="Отмена" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> У Ð²Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть не более [MAX_AGENTS] допущенных жителей. </notification> @@ -1723,14 +1734,6 @@ http://secondlife.com/download. Ðевозможно покинуть группу. Ð’Ñ‹ не можете покинуть группу, так как вы ее поÑледний владелец. Сначала назначьте владельцем другого учаÑтника. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="GroupDepartError"> - Ðевозможно покинуть группу: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Ð’Ñ‹ покинули группу [group_name]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="ConfirmKick"> Ð’Ñ‹ ДЕЙСТВИТЕЛЬÐО хотите выброÑить вÑех жителей Ñ Ñетки? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="ВыброÑить вÑех жителей"/> @@ -2400,6 +2403,10 @@ http://secondlife.com/download. Ð’Ñ‹ дейÑтвительно хотите необратимо удалить Ñодержимое корзины? <usetemplate ignoretext="Подтверждать перед опорожнением корзины инвентарÑ" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Ваша корзина переполнена. Ðто может вызвать проблемы при входе. + <usetemplate name="okcancelbuttons" notext="Я очищу корзину позже" yestext="ОчиÑтить корзину ÑейчаÑ"/> + </notification> <notification name="ConfirmClearBrowserCache"> Ð’Ñ‹ дейÑтвительно хотите удалить журнал Ñвоих перемещений, веб-Ñтраниц и поиÑка? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> @@ -3257,11 +3264,15 @@ http://secondlife.com/download. <notification name="AttachmentSaved"> ПриÑоединение Ñохранено. </notification> - <notification name="PresetNotSaved"> - Ошибка при Ñохранении преÑета [NAME]. + <notification name="AppearanceToXMLSaved"> + ВнешноÑÑ‚ÑŒ Ñохранена в формате XML в [PATH] </notification> - <notification name="PresetNotDeleted"> - Ошибка при удалении преÑета [NAME]. + <notification name="AppearanceToXMLFailed"> + Ðе удалоÑÑŒ Ñохранить внешноÑÑ‚ÑŒ в XML. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +Ошибка при удалении преÑета [NAME]. </notification> <notification name="UnableToFindHelpTopic"> Ðевозможно найти раздел Ñправки Ð´Ð»Ñ Ñтого Ñлемента. @@ -4075,6 +4086,9 @@ http://secondlife.com/download. <notification name="CantAttachNotEnoughScriptResources"> ÐедоÑтаточно Ñвободных реÑурÑов Ñкриптинга Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°! </notification> + <notification name="IllegalAttachment"> + ПрикреплÑемый объект потребовал неÑущеÑтвующей точки на аватаре. Он был прикреплен к груди. + </notification> <notification name="CantDropItemTrialUser"> ЗдеÑÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ ÑбраÑывать объекты; перейдите в беÑплатную облаÑÑ‚ÑŒ Ð´Ð»Ñ Ð³Ð¾Ñтей. </notification> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml index 9d7ae546fd4e78fc36206478d5ce117bd3288233..48e03b98e897f23af3a964241dd6e8df81893eed 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Сообщать мне: </text> - <check_box label="о раÑходах и доходах" name="notify_money_change_checkbox"/> + <check_box label="О раÑходах" name="notify_money_spend_checkbox"/> <check_box label="о входе и выходе моих друзей" name="friends_online_notify_checkbox"/> + <check_box label="О доходах" name="notify_money_received_checkbox"/> <text name="show_label"> Ð’Ñегда показывать: </text> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml index 31c9b2135d4aef5f44273869d599e5d77109b3be..200241bd4dcbc53ee6da7c81d3dcc3745874cbc0 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> КачеÑтвенней </text> + <slider label="МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑложноÑÑ‚ÑŒ аватара:" name="IndirectMaxComplexity" tool_tip="Указывает раÑÑтоÑние, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ визуально Ñложный аватар риÑуетÑÑ ÐºÐ°Ðº мармеладный мишка"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="ÐтмоÑферные шейдеры" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="РаÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ оÑвещениÑ" name="UseLightShaders"/> <button label="Сохранить наÑтройки как преÑет..." name="PrefSaveButton"/> <button label="Загрузить преÑет..." name="PrefLoadButton"/> + min_val="0,125" <button label="Удалить преÑет..." name="PrefDeleteButton"/> <button label="Вернуть рекомендуемые наÑтройки" name="Defaults"/> <button label="РаÑширенные наÑтройки..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/ru/panel_sound_devices.xml b/indra/newview/skins/default/xui/ru/panel_sound_devices.xml index 98dab288a36c7e623faff66a90980893d5193de5..3de84fb937f5b3bcf4ee21cc887d359f1ecab5e1 100644 --- a/indra/newview/skins/default/xui/ru/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/ru/panel_sound_devices.xml @@ -16,9 +16,9 @@ Выход </text> <text name="My volume label"> - ÐœÐ¾Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾ÑÑ‚ÑŒ: + ГромкоÑÑ‚ÑŒ микрофона: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Измените значение, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿Ð¾Ð»Ð·ÑƒÐ½Ð¾Ðº"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Измените уровень в микрофоне, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿Ð¾Ð»Ð·ÑƒÐ½Ð¾Ðº"/> <text name="wait_text"> Подождите </text> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 04bb55c965b3cef71a0d57a02962f0711d92a9d3..da03af055c070746ac969194245891a8269fc1d5 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ [BUILD_CONFIG] + </string> <string name="AboutPosition"> Ð’Ñ‹ в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», раÑположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -72,6 +75,9 @@ SLURL: <nolink>[SLURL]</nolink> <string name="ErrorFetchingServerReleaseNotesURL"> Ошибка при получении URL-адреÑа заметок о выпуÑке Ñервера. </string> + <string name="BuildConfiguration"> + ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ + </string> <string name="ProgressRestoring"> ВоÑÑтановление... </string> @@ -1387,6 +1393,9 @@ support@secondlife.com. <string name="BodyPartsRightLeg"> ÐŸÑ€Ð°Ð²Ð°Ñ Ð½Ð¾Ð³Ð° </string> + <string name="BodyPartsEnhancedSkeleton"> + Улучшенный Ñкелет + </string> <string name="GraphicsQualityLow"> Ð½Ð¸Ð·ÐºÐ°Ñ </string> @@ -1835,6 +1844,51 @@ support@secondlife.com. <string name="Avatar Center"> Центр аватара </string> + <string name="Left Ring Finger"> + Левый безымÑнный палец + </string> + <string name="Right Ring Finger"> + Правый безымÑнный палец + </string> + <string name="Tail Base"> + ОÑнование хвоÑта + </string> + <string name="Tail Tip"> + Кончик хвоÑта + </string> + <string name="Left Wing"> + Левое крыло + </string> + <string name="Right Wing"> + Правое крыло + </string> + <string name="Jaw"> + ПаÑÑ‚ÑŒ + </string> + <string name="Alt Left Ear"> + Ðльт. левое ухо + </string> + <string name="Alt Right Ear"> + Ðльт. правое ухо + </string> + <string name="Alt Left Eye"> + Ðльт. левый глаз + </string> + <string name="Alt Right Eye"> + Ðльт. правый глаз + </string> + <string name="Tongue"> + Язык + </string> + <string name="Groin"> + Пах + </string> + <string name="Left Hind Foot"> + Ð›ÐµÐ²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> + <string name="Right Hind Foot"> + ÐŸÑ€Ð°Ð²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> <string name="Invalid Attachment"> ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ </string> @@ -2224,12 +2278,12 @@ support@secondlife.com. <string name="ATTACH_BELLY"> Живот </string> - <string name="ATTACH_RPEC"> - ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Ð›ÐµÐ²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ </string> + <string name="ATTACH_RIGHT_PEC"> + ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ + </string> <string name="ATTACH_HUD_CENTER_2"> Данные в игре в центре 2 </string> @@ -2260,6 +2314,51 @@ support@secondlife.com. <string name="ATTACH_AVATAR_CENTER"> Центр аватара </string> + <string name="ATTACH_LHAND_RING1"> + Левый безымÑнный палец + </string> + <string name="ATTACH_RHAND_RING1"> + Правый безымÑнный палец + </string> + <string name="ATTACH_TAIL_BASE"> + ОÑнование хвоÑта + </string> + <string name="ATTACH_TAIL_TIP"> + Кончик хвоÑта + </string> + <string name="ATTACH_LWING"> + Левое крыло + </string> + <string name="ATTACH_RWING"> + Правое крыло + </string> + <string name="ATTACH_FACE_JAW"> + ПаÑÑ‚ÑŒ + </string> + <string name="ATTACH_FACE_LEAR"> + Ðльт. левое ухо + </string> + <string name="ATTACH_FACE_REAR"> + Ðльт. правое ухо + </string> + <string name="ATTACH_FACE_LEYE"> + Ðльт. левый глаз + </string> + <string name="ATTACH_FACE_REYE"> + Ðльт. правый глаз + </string> + <string name="ATTACH_FACE_TONGUE"> + Язык + </string> + <string name="ATTACH_GROIN"> + Пах + </string> + <string name="ATTACH_HIND_LFOOT"> + Ð›ÐµÐ²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> + <string name="ATTACH_HIND_RFOOT"> + ÐŸÑ€Ð°Ð²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> <string name="CursorPos"> Строка [LINE], Ñтолбец [COLUMN] </string> @@ -4247,10 +4346,10 @@ support@secondlife.com. Оффлайн </string> <string name="not_online_msg"> - Пользователь оффлайн - Ñообщение будет Ñохранено и доÑтавлено позже. + Пользователь не в онлайне - Ñообщение будет Ñохранено и доÑтавлено позже. </string> <string name="not_online_inventory"> - Пользователь оффлайн - инвентарь Ñохранен. + Пользователь не в онлайне - инвентарь Ñохранен. </string> <string name="answered_call"> Ðа ваш звонок ответили diff --git a/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml index 53938117fde29ca6fb0e5f0bd4d1a7f1f073a689..867e15a3caf966ea540678d49351c42b9110648d 100644 --- a/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Maksimum karmaşıklık:" name="IndirectMaxComplexity" tool_tip="Görsel olarak karmaşık yapıdaki bir avatarın hangi noktada jelibon gibi tek renkli olarak çizileceÄŸini kontrol eder"/> + <slider label="Maksimum karmaşıklık:" name="IndirectMaxComplexity" tool_tip="Görsel olarak karmaşık bir avatarın hangi noktadan itibaren JellyDolll olarak çizileceÄŸini kontrol eder"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_other.xml b/indra/newview/skins/default/xui/tr/menu_attachment_other.xml index 8a669a28f7e7ba92b4d2743c56986c0f6be94d86..d09174dcc0985836ebf05943a355b95cd2667b04 100644 --- a/indra/newview/skins/default/xui/tr/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/tr/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="AÄ°" name="Send IM..."/> <menu_item_call label="Ara" name="Call"/> <menu_item_call label="Gruba Davet Et" name="Invite..."/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> <menu_item_call label="Engelle" name="Avatar Mute"/> <menu_item_call label="Raporla" name="abuse"/> <menu_item_call label="Dondur" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml index c49f817a45af21526bd64dab321ae7040d2e4fa5..9027f09d8eb195d0563a0685ca24ff29145accfe 100644 --- a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="Dış Görünümümü Düzenle" name="Edit Outfit"/> <menu_item_call label="Åžeklimi Düzenle" name="Edit My Shape"/> <menu_item_call label="Konum YüksekliÄŸi" name="Hover Height"/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> <menu_item_call label="ArkadaÅŸlarım" name="Friends..."/> <menu_item_call label="Gruplarım" name="Groups..."/> <menu_item_call label="Profilim" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_other.xml b/indra/newview/skins/default/xui/tr/menu_avatar_other.xml index e4ba3a56167bae34569c6a25b4eb862f67e526f4..9e95b3033a574f725daa97c1160f022e42e7df30 100644 --- a/indra/newview/skins/default/xui/tr/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/tr/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="AÄ°" name="Send IM..."/> <menu_item_call label="Ara" name="Call"/> <menu_item_call label="Gruba Davet Et" name="Invite..."/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> <menu_item_call label="Engelle" name="Avatar Mute"/> <menu_item_call label="Raporla" name="abuse"/> <menu_item_call label="Dondur" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_self.xml b/indra/newview/skins/default/xui/tr/menu_avatar_self.xml index 4dfa42c3470517e7ce23b259af185930f5b3786c..3078733478510ef0686bb92221d7820bd699d6b4 100644 --- a/indra/newview/skins/default/xui/tr/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/tr/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="Dış Görünümümü Düzenle" name="Edit Outfit"/> <menu_item_call label="Åžeklimi Düzenle" name="Edit My Shape"/> <menu_item_call label="Konum YüksekliÄŸi" name="Hover Height"/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> <menu_item_call label="ArkadaÅŸlarım" name="Friends..."/> <menu_item_call label="Gruplarım" name="Groups..."/> <menu_item_call label="Profilim" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index 324e549a757a048fe87ee00a6f67f7649de5affa..39636f2ebfc5bca78259b835035f6a24fecf79ea 100644 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Rahatsız Etme" name="Do Not Disturb"/> </menu> <menu_item_call label="L$ Satın Al..." name="Buy and Sell L$"/> - <menu_item_call label="Satıcı Giden Kutusu..." name="MerchantOutbox"/> <menu_item_call label="Pazaryeri ilanları..." name="MarketplaceListings"/> <menu_item_call label="Hesap kontrol paneli..." name="Manage My Account"/> <menu_item_call label="Tercihler..." name="Preferences"/> @@ -419,6 +418,7 @@ <menu_item_check label="Ayrıntı Seviyesi Bilgisini Devre Dışı Bırak" name="Disable LOD"/> <menu_item_check label="Debug Character Vis" name="Debug Character Vis"/> <menu_item_check label="Çarpışma Ä°skeletini Göster" name="Show Collision Skeleton"/> + <menu_item_check label="Kemikleri Göster" name="Show Bones"/> <menu_item_check label="Aracı Hedefini Göster" name="Display Agent Target"/> <menu_item_call label="Aksesuarların Dökümünü Al" name="Dump Attachments"/> <menu_item_call label="Avatar Dokuları İçin Hata Ayıklama" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index a982dc03ed29aec39d20bd18bb74800a77bec0a9..fb38486a9e33617be151a3ee8edc9453950578f4 100644 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -480,6 +480,9 @@ Dış görünüm klasöründe hiç giysi, vücut bölümü ya da aksesuar yok. <notification name="CannotWearInfoNotComplete"> Bu öğe henüz yüklenmediÄŸi için kullanamazsınız. Lütfen bir dakika sonra tekrar deneyin. </notification> + <notification name="MustEnterPasswordToLogIn"> + Oturum açmak için lütfen parolanızı girin. + </notification> <notification name="MustHaveAccountToLogIn"> Hata! BoÅŸ bırakılan alan(lar) var. Avatarınızın Kullanıcı adını girmeniz gerekmektedir. @@ -548,6 +551,9 @@ Not: Bu iÅŸlem önbelleÄŸi temizleyecek. <notification name="ChangeConnectionPort"> Port ayarları, [APP_NAME] uygulamasını yeniden baÅŸlattıktan sonra geçerli olur. </notification> + <notification name="ChangeDeferredDebugSetting"> + Bu hata ayıklama ayarı deÄŸiÅŸikliÄŸi [APP_NAME] uygulamasını yeniden baÅŸlattıktan sonra geçerli olacak. + </notification> <notification name="ChangeSkin"> Yeni dış katman [APP_NAME] uygulamasını yeniden baÅŸlattıktan sonra görüntülenecek. </notification> @@ -1366,12 +1372,13 @@ Yeni bir ana konum ayarlamak isteyebilirsiniz. <ignore name="ignore" text="Giysilerin karşıdan yüklenmesi uzun zaman alıyor"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Görsel karmaşıklık] seviyeniz: [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] düzeyiniz [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avatarımın karmaşıklık düzeyi çok yüksekse beni uyar" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Görsel karmaşıklık] seviyeniz: [AGENT_COMPLEXITY]. + [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] düzeyiniz [AGENT_COMPLEXITY]. </notification> <notification name="FirstRun"> [APP_NAME] yüklemesi tamamlandı. @@ -1486,6 +1493,10 @@ Lütfen sadece bir nesne seçin ve tekrar deneyin. Geçerli yüzeyi bu ÅŸekilde kaydetmeyi, yüzey yükseltme/alçaltma sınırları için merkez olarak kullanmayı ve 'Geri Çevir' aracı için varsayılan olarak ayarlamayı gerçekten istiyor musunuz? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="ConfirmTextureHeights"> + Yükselti Ayarları için girdiÄŸiniz düşük deÄŸer, yüksek deÄŸerden daha fazla. Devam edilsin mi? + <usetemplate canceltext="Tekrar Sorma" name="yesnocancelbuttons" notext="Ä°ptal Et" yestext="Tamam"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Sadece [MAX_AGENTS] tane Ä°zin Verilen Sakin belirleyebilirsiniz. </notification> @@ -1723,14 +1734,6 @@ Gruptan ayrılmak istiyor musunuz? Gruptan ayrılınamıyor. Gruptan ayrılamazsınız çünkü grubun son sahibisiniz. Lütfen önce sahip rolüne baÅŸka bir üye atayın. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="GroupDepartError"> - Gruptan ayrılma iÅŸlemi yapılamıyor: [reason]. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="GroupDepart"> - [group_name] grubundan ayrıldınız. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> <notification name="ConfirmKick"> Tüm Sakinleri GERÇEKTEN aÄŸ dışına çıkarmak istiyor musunuz? <usetemplate name="okcancelbuttons" notext="Ä°ptal Et" yestext="Tüm Sakinleri Çıkar"/> @@ -2400,6 +2403,10 @@ Bu iÅŸlemi tamamlamadan önce Rahatsız Etme'yi kapatmak ister misiniz? Çöp kutunuzun içeriÄŸini kalıcı olarak silmek istediÄŸinize emin misiniz? <usetemplate ignoretext="Envanter Çöp Kutusu klasörünü boÅŸaltmadan önce doÄŸrulama iste" name="okcancelignore" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="TrashIsFull"> + Çöpte yer kalmamış. Bu durum oturum açma sırasında sorun yaÅŸamanıza neden olabilir. + <usetemplate name="okcancelbuttons" notext="Çöpü daha sonra boÅŸaltacağım" yestext="Çöp kutusunu ÅŸimdi boÅŸalt"/> + </notification> <notification name="ConfirmClearBrowserCache"> Seyahat, web ve arama geçmiÅŸinizi silmek istediÄŸinize emin misiniz? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> @@ -2984,7 +2991,7 @@ Bu bölgede kalmaya devam ederseniz oturumunuz sonlandırılacak. Bu bölgede kalmaya devam ederseniz oturumunuz sonlandırılacak. </notification> <notification name="LoadWebPage"> - [URL] web sayfası yüklensin mi? + Bu web sayfası yüklensin mi: [URL] ? [MESSAGE] @@ -3257,11 +3264,15 @@ GüvenliÄŸiniz için birkaç saniye engellenecek. <notification name="AttachmentSaved"> Aksesuar kaydedildi. </notification> - <notification name="PresetNotSaved"> - [NAME] ön ayarı kaydedilirken hata oluÅŸtu. + <notification name="AppearanceToXMLSaved"> + Görünüm XML olarak [PATH] konumuna kaydedildi </notification> - <notification name="PresetNotDeleted"> - [NAME] ön ayarı silinirken hata oluÅŸtu. + <notification name="AppearanceToXMLFailed"> + Görünüm XML olarak kaydedilemedi. + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +[NAME] ön ayarı silinirken hata oluÅŸtu. </notification> <notification name="UnableToFindHelpTopic"> Bu öğe için yardım baÅŸlığı bulunamıyor. @@ -4069,6 +4080,9 @@ Lütfen bir dakika sonra tekrar deneyin. <notification name="CantAttachNotEnoughScriptResources"> Nesneyi iliÅŸtirmek için yeterli komut dosyası kaynağı mevcut deÄŸil! </notification> + <notification name="IllegalAttachment"> + Aksesuar avatarda var olmayan bir noktaya karşılık geliyor. Bunun yerine göğüs kısmına eklendi. + </notification> <notification name="CantDropItemTrialUser"> Buraya nesne düşüremezsiniz; Ãœcretsiz Deneme alanını deneyin. </notification> diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml index 46a4793c5314592d305a1d98b94dbd0fc57a4337..b0f026b285a3c00980f5e5e4e54ad6ee0d157321 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Bana söyle: </text> - <check_box label="L$ harcadığımda veya aldığımda" name="notify_money_change_checkbox"/> + <check_box label="L$ harcadığımda" name="notify_money_spend_checkbox"/> <check_box label="ArkadaÅŸlarım oturum açtığında veya kapattığında" name="friends_online_notify_checkbox"/> + <check_box label="L$ aldığımda" name="notify_money_received_checkbox"/> <text name="show_label"> Daima göster: </text> diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml index 13984c2792d804dde8b6498bc210a24202af86fa..9cfa7d61f4e66e8b49692f399e166a77f6f57b20 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Daha iyi </text> + <slider label="Avatarın Maksimum Karmaşıklığı:" name="IndirectMaxComplexity" tool_tip="Görsel olarak karmaşık bir avatarın hangi noktadan itibaren JellyDolll olarak çizileceÄŸini kontrol eder"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Atmosferik gölgeleyiciler" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="GeliÅŸmiÅŸ Aydınlatma Modeli" name="UseLightShaders"/> <button label="Ayarları ön ayar olarak kaydet..." name="PrefSaveButton"/> <button label="Ön ayarı yükle..." name="PrefLoadButton"/> + min_val="0,125" <button label="Ön ayarı sil..." name="PrefDeleteButton"/> <button label="Önerilen ayarlara dön" name="Defaults"/> <button label="GeliÅŸmiÅŸ Ayarlar..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/tr/panel_sound_devices.xml b/indra/newview/skins/default/xui/tr/panel_sound_devices.xml index 982ef2ea3bf28e08b1d14c948e0ce10bfb027f77..be3299b89c342677aae63802efe8dc6f0acaf520 100644 --- a/indra/newview/skins/default/xui/tr/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/tr/panel_sound_devices.xml @@ -16,9 +16,9 @@ Çıktı </text> <text name="My volume label"> - Ses düzeyim: + Mik. ses düzeyi: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Bu kaydırıcıyı kullanarak ses düzeyini deÄŸiÅŸtirin"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Bu kaydırma butonunu kullanarak mikrofonun ses düzeyini deÄŸiÅŸtirin"/> <text name="wait_text"> Lütfen bekleyin </text> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index 67c91979077000c144bdf046e796b288f005c63d..6aad65da22d2c3faeb937fae7c6c7e2bf9df0ecd 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -39,7 +39,10 @@ </string> <string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) -[[VIEWER_RELEASE_NOTES_URL] [Sürüm Notları]] +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Yapı Konfigürasyonu [BUILD_CONFIG] </string> <string name="AboutPosition"> <nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız @@ -59,12 +62,12 @@ Grafik Kartı: [GRAPHICS_CARD] Windows Grafik Sürücüsü Sürümü: [GRAPHICS_DRIVER_VERSION] </string> <string name="AboutLibs"> - OpenGL Sürümü: [OPENGL_VERSION] + OpenGL Sürümü [OPENGL_VERSION] J2C Kod Çözücü Sürümü: [J2C_VERSION] Ses Sürücüsü Sürümü: [AUDIO_DRIVER_VERSION] LLCEFLib/CEF Sürümü: [LLCEFLIB_VERSION] -Ses Sunucusu Sürümü: [VOICE_VERSION] +Ses Sunucu Sürümü: [VOICE_VERSION] </string> <string name="AboutTraffic"> Kaybolan Paketler: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -72,6 +75,9 @@ Ses Sunucusu Sürümü: [VOICE_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> Sunucu sürümü notları URL'si alınırken hata oluÅŸtu. </string> + <string name="BuildConfiguration"> + Yapı Konfigürasyonu + </string> <string name="ProgressRestoring"> Geri yükleniyor... </string> @@ -1387,6 +1393,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="BodyPartsRightLeg"> SaÄŸ Bacak </string> + <string name="BodyPartsEnhancedSkeleton"> + GeliÅŸmiÅŸ Ä°skelet + </string> <string name="GraphicsQualityLow"> Düşük </string> @@ -1835,6 +1844,51 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="Avatar Center"> Avatar Merkezi </string> + <string name="Left Ring Finger"> + Sol Yüzük Parmağı + </string> + <string name="Right Ring Finger"> + SaÄŸ Yüzük Parmağı + </string> + <string name="Tail Base"> + Kuyruk Tabanı + </string> + <string name="Tail Tip"> + Kuyruk Ucu + </string> + <string name="Left Wing"> + Sol Kanat + </string> + <string name="Right Wing"> + SaÄŸ Kanat + </string> + <string name="Jaw"> + Pençe + </string> + <string name="Alt Left Ear"> + Altrntf Sol Kulak + </string> + <string name="Alt Right Ear"> + Altrntf SaÄŸ Kulak + </string> + <string name="Alt Left Eye"> + Altrntf Sol Göz + </string> + <string name="Alt Right Eye"> + Altrntf SaÄŸ Göz + </string> + <string name="Tongue"> + Dil + </string> + <string name="Groin"> + Kasık + </string> + <string name="Left Hind Foot"> + Sol Arka Ayak + </string> + <string name="Right Hind Foot"> + SaÄŸ Arka Ayak + </string> <string name="Invalid Attachment"> Geçersiz Aksesuar Noktası </string> @@ -2224,12 +2278,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ATTACH_BELLY"> Göbek </string> - <string name="ATTACH_RPEC"> - SaÄŸ Göğüs - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Sol Göğüs </string> + <string name="ATTACH_RIGHT_PEC"> + SaÄŸ Göğüs + </string> <string name="ATTACH_HUD_CENTER_2"> BÃœG 2. Merkez </string> @@ -2260,6 +2314,51 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ATTACH_AVATAR_CENTER"> Avatar Merkezi </string> + <string name="ATTACH_LHAND_RING1"> + Sol Yüzük Parmağı + </string> + <string name="ATTACH_RHAND_RING1"> + SaÄŸ Yüzük Parmağı + </string> + <string name="ATTACH_TAIL_BASE"> + Kuyruk Tabanı + </string> + <string name="ATTACH_TAIL_TIP"> + Kuyruk Ucu + </string> + <string name="ATTACH_LWING"> + Sol Kanat + </string> + <string name="ATTACH_RWING"> + SaÄŸ Kanat + </string> + <string name="ATTACH_FACE_JAW"> + Pençe + </string> + <string name="ATTACH_FACE_LEAR"> + Altrntf Sol Kulak + </string> + <string name="ATTACH_FACE_REAR"> + Altrntf SaÄŸ Kulak + </string> + <string name="ATTACH_FACE_LEYE"> + Altrntf Sol Göz + </string> + <string name="ATTACH_FACE_REYE"> + Altrntf SaÄŸ Göz + </string> + <string name="ATTACH_FACE_TONGUE"> + Dil + </string> + <string name="ATTACH_GROIN"> + Kasık + </string> + <string name="ATTACH_HIND_LFOOT"> + Sol Arka Ayak + </string> + <string name="ATTACH_HIND_RFOOT"> + SaÄŸ Arka Ayak + </string> <string name="CursorPos"> Satır [LINE], Sütun [COLUMN] </string> @@ -4249,6 +4348,12 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="OfflineStatus"> Çevrimdışı </string> + <string name="not_online_msg"> + Kullanıcı çevrimiçi deÄŸil - mesaj saklanıp daha sonra iletilecek. + </string> + <string name="not_online_inventory"> + Kullanıcı çevrimiçi deÄŸil - envanter kaydedildi. + </string> <string name="answered_call"> Aramanız yanıtlandı </string> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml index f9c2fe47e7d86590b63cdd7c7c3b5effef891888..2a00bb617215c4896df27b1c2a78cdd2a4255e48 100644 --- a/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> 化身 </text> - <slider label="最大複雜度:" name="IndirectMaxComplexity" tool_tip="控制在何時機下讓複雜化身呈åƒç‚ºã€Œå–®è‰²è»Ÿç³–娃娃ã€"/> + <slider label="最大複雜度:" name="IndirectMaxComplexity" tool_tip="控制在何時機下讓複雜化身呈åƒç‚º JellyDoll"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml index ace1302250d19bb8f0ba6a3a16098a61951a4c12..69bc4e7632d0be5062150c9c90ffe0025d8622ce 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="é‚€è«‹åŠ å…¥ç¾¤çµ„" name="Invite..."/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> <menu_item_call label="å°éŽ–" name="Avatar Mute"/> <menu_item_call label="å›žå ±" name="abuse"/> <menu_item_call label="å‡çµ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml index d9e6eff897a2842fbc3996434162849f3888f55a..cf56d7c86bf73acd571ef684bcf0e2bbc8896502 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml @@ -9,6 +9,7 @@ <menu_item_call label="編輯我的è£æ‰®" name="Edit Outfit"/> <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="懸浮高度" name="Hover Height"/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> <menu_item_call label="我的個人檔案" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml index 0e0d1cc3d2c31dc0ffd63cdd5e01e7e653904af2..b58ec1d8cb7e25e10c29d2d1ff25e6899ceae119 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml @@ -6,6 +6,7 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="é‚€è«‹åŠ å…¥ç¾¤çµ„" name="Invite..."/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> <menu_item_call label="å°éŽ–" name="Avatar Mute"/> <menu_item_call label="å›žå ±" name="abuse"/> <menu_item_call label="å‡çµ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml index a644a45df6888d16b481f4b9b9261b0d489b29eb..e2ddb573070ff51035c21771261b02247a14de38 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml @@ -26,6 +26,7 @@ <menu_item_call label="編輯我的è£æ‰®" name="Edit Outfit"/> <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="懸浮高度" name="Hover Height"/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> <menu_item_call label="我的個人檔案" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index 41590d60c70e8cf000977baec747e1cff4f319ae..f2971491ac5e38159b4235c03c62ad5c704e3b46 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="請勿打擾" name="Do Not Disturb"/> </menu> <menu_item_call label="購買 L$…" name="Buy and Sell L$"/> - <menu_item_call label="商家發件匣…" name="MerchantOutbox"/> <menu_item_call label="Marketplace 刊登…" name="MarketplaceListings"/> <menu_item_call label="帳戶主控臺…" name="Manage My Account"/> <menu_item_call label="å好è¨å®šâ€¦" name="Preferences"/> @@ -419,6 +418,7 @@ <menu_item_check label="åœç”¨ç´°ç¯€å±¤æ¬¡" name="Disable LOD"/> <menu_item_check label="除錯å—å…ƒå¯è¦‹æ€§" name="Debug Character Vis"/> <menu_item_check label="顯示碰撞骨架" name="Show Collision Skeleton"/> + <menu_item_check label="顯示骨é " name="Show Bones"/> <menu_item_check label="顯示用戶目標" name="Display Agent Target"/> <menu_item_call label="傾å°é™„件" name="Dump Attachments"/> <menu_item_call label="除錯化身æ質" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index 3f08496a6826984d56d809869a7f4bb6bfdc4f8f..463afab1c09c0d08ca1184fcc15b54ad4af235dc 100644 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -480,6 +480,9 @@ <notification name="CannotWearInfoNotComplete"> 無法穿戴該物件,它尚未完æˆè¼‰å…¥ã€‚ è«‹ç¨å€™å†è©¦ã€‚ </notification> + <notification name="MustEnterPasswordToLogIn"> + 請輸入密碼以便登入。 + </notification> <notification name="MustHaveAccountToLogIn"> ç³Ÿç³•ï¼ ç™¼ç¾æœ‰å…§å®¹ç•™ç™½ã€‚ ä½ å¿…é ˆç‚ºåŒ–èº«è¼¸å…¥ä¸€å€‹ä½¿ç”¨è€…å稱。 @@ -548,6 +551,9 @@ <notification name="ChangeConnectionPort"> é‡æ–°å•Ÿå‹• [APP_NAME] å¾Œå°‡å•Ÿç”¨æ–°çš„åŸ è¨å®šã€‚ </notification> + <notification name="ChangeDeferredDebugSetting"> + 這個除錯è¨å®šå°‡åœ¨é‡æ–°å•Ÿå‹• [APP_NAME] 後啟用。 + </notification> <notification name="ChangeSkin"> é‡æ–°å•Ÿå‹• [APP_NAME] 後將顯ç¾æ–°çš„皮膚。 </notification> @@ -1359,12 +1365,13 @@ <ignore name="ignore" text="æœè£èŠ±å¤ªå¤šæ™‚間下載"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 視覺複雜度]是[AGENT_COMPLEXITY]。 + <notification name="AgentComplexityWithVisibility"> + ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 化身複雜度]是[AGENT_COMPLEXITY]。 [OVERLIMIT_MSG] + <usetemplate ignoretext="è¦å‘Šæˆ‘化身的複雜度是å¦å¯èƒ½éŽé«˜" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 視覺複雜度]是[AGENT_COMPLEXITY]。 + ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 化身複雜度]是[AGENT_COMPLEXITY]。 </notification> <notification name="FirstRun"> [APP_NAME] 安è£å®Œæˆã€‚ @@ -1479,6 +1486,10 @@ SHA1 指紋:[MD5_DIGEST] ä½ çœŸçš„è¦ç¢ºå®šç”¢å‡ºç›®å‰åœ°å½¢ï¼Œä½¿å…¶æˆç‚ºåœ°å½¢å‡/é™æ¥µé™çš„ä¸é–“值,並è¨ç‚ºã€Œå¾©åŽŸã€å·¥å…·çš„é è¨å€¼ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> </notification> + <notification name="ConfirmTextureHeights"> + ä½ è¨çš„海拔範åœå€¼ï¼Œä½Žå€¼å¤§æ–¼é«˜å€¼ã€‚  繼續? + <usetemplate canceltext="ä¸è¦å•" name="yesnocancelbuttons" notext="å–消" yestext="確定"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> ä½ æœ€å¤šåªèƒ½æœ‰ [MAX_AGENTS] ä½å…許居民。 </notification> @@ -1713,14 +1724,6 @@ SHA1 指紋:[MD5_DIGEST] 無法離開群組。 ä½ æ˜¯æ¤ç¾¤çµ„僅å˜çš„所有人,ä¸å¾—離開群組。 請先把所有人è·éŠœæŒ‡æ´¾çµ¦å¦ä¸€äººã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="GroupDepartError"> - 無法離開群組:[reason]。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="GroupDepart"> - ä½ å·²ç¶“é›¢é–‹[group_name]群組。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> <notification name="ConfirmKick"> ä½ ç¢ºå®šè¦è¸¢å‡ºé€™ç¶²æ ¼å…§çš„全部居民? <usetemplate name="okcancelbuttons" notext="å–消" yestext="踢出全部居民"/> @@ -2390,6 +2393,10 @@ SHA1 指紋:[MD5_DIGEST] ä½ ç¢ºå®šä½ è¦å°ä½ 垃圾ç’ä¸çš„內容進行刪除? <usetemplate ignoretext="在我清空收ç´å€åžƒåœ¾ç’資料夾å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/> </notification> + <notification name="TrashIsFull"> + ä½ çš„åžƒåœ¾æ¡¶å¿«æ»¿äº†ã€‚ 這å¯èƒ½æœƒé€ æˆç™»å…¥çš„å•é¡Œã€‚ + <usetemplate name="okcancelbuttons" notext="我ç¨å¾Œå†æ¸…空垃圾桶" yestext="ç¾åœ¨æ¸…空垃圾桶"/> + </notification> <notification name="ConfirmClearBrowserCache"> ä½ ç¢ºå®šè¦åˆªé™¤ä½ çš„æ—…è¡Œã€ç¶²é åŠæœå°‹æ·å²ç´€éŒ„嗎? <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> @@ -2973,11 +2980,11 @@ SHA1 指紋:[MD5_DIGEST] å¦‚æžœä½ ç¹¼çºŒç•™åœ¨é€™åœ°å€ï¼Œä½ 將會被登出。 </notification> <notification name="LoadWebPage"> - 載入網é [URL]? + 載入網é [URL]? [MESSAGE] -來æºç‰©ä»¶ï¼š<nolink>[OBJECTNAME]</nolink>(所有人:[NAME_SLURL]) +來æºç‰©ä»¶ï¼š<nolink>[OBJECTNAME]</nolink>(所有人是[NAME_SLURL]) <form name="form"> <button name="Gotopage" text="å‰å¾€é é¢"/> <button name="Cancel" text="å–消"/> @@ -3246,11 +3253,15 @@ SHA1 指紋:[MD5_DIGEST] <notification name="AttachmentSaved"> 附件已儲å˜ã€‚ </notification> - <notification name="PresetNotSaved"> - 儲å˜é è¨å稱[NAME]時出錯。 + <notification name="AppearanceToXMLSaved"> + 外觀已經å˜æˆä½æ–¼[PATH]çš„XML </notification> - <notification name="PresetNotDeleted"> - 刪除é è¨å稱[NAME]時出錯。 + <notification name="AppearanceToXMLFailed"> + 將外觀å˜ç‚ºXML失敗。 + icon="notifytip.tga" + name="PresetNotDeleted" + type="notifytip"> +刪除é è¨å稱[NAME]時出錯。 </notification> <notification name="UnableToFindHelpTopic"> 找ä¸åˆ°é€™å€‹å…ƒä»¶çš„幫助主題。 @@ -4065,6 +4076,9 @@ SHA1 指紋:[MD5_DIGEST] <notification name="CantAttachNotEnoughScriptResources"> 腳本資æºä¸è¶³ï¼Œç„¡æ³•é™„è‘—ç‰©ä»¶ï¼ </notification> + <notification name="IllegalAttachment"> + 這個附件è¦æ±‚了化身上ä¸å˜åœ¨çš„點。 å› æ¤å·²å°‡è©²é™„件附著到胸部。 + </notification> <notification name="CantDropItemTrialUser"> ä½ ç„¡æ³•åœ¨æ¤å¸é™¤ç‰©ä»¶ï¼Œè«‹åˆ°ã€Œè‡ªç”±å˜—試ã€å€åŸŸå†è©¦ã€‚ </notification> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml index 94eb3c1389471229e7c40ae7308ef911b6d37f95..212880df55492492b4c184d99a6f0a44ffa0fdd2 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> 告訴我: </text> - <check_box label="當我花費或å–å¾— L$" name="notify_money_change_checkbox"/> + <check_box label="當我花用 L$ 時" name="notify_money_spend_checkbox"/> <check_box label="當我的朋å‹ä¸Šç·šæˆ–離線" name="friends_online_notify_checkbox"/> + <check_box label="當我得到 L$ 時" name="notify_money_received_checkbox"/> <text name="show_label"> 總是顯示: </text> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml index 8c4d2f9c1824f172cd0e2d435df60fe5c88ea0fe..b5c36668f64f6ce75b2fa13acee18d81c65ccd37 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> 最佳 </text> + <slider label="化身最大複雜度:" name="IndirectMaxComplexity" tool_tip="控制在何時機下讓複雜化身呈åƒç‚º JellyDoll"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="大氣著色" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="進階照明模型" name="UseLightShaders"/> <button label="å°‡è¨å®šå˜ç‚ºé è¨å€¼ …" name="PrefSaveButton"/> <button label="載入é è¨..." name="PrefLoadButton"/> + min_val="0.125" <button label="刪除自訂é…置…" name="PrefDeleteButton"/> <button label="é‡è¨ç‚ºæˆ‘們建è°çš„è¨å®š" name="Defaults"/> <button label="進階è¨å®šâ€¦" name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/zh/panel_sound_devices.xml b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml index fa4e24a6059d770fc8ca92ce19f2b603d6fc23e6..e29ffe31af7cdefc06dd4cfd93c2dc2de03c66fd 100644 --- a/indra/newview/skins/default/xui/zh/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml @@ -16,9 +16,9 @@ 輸出 </text> <text name="My volume label"> - 我的音é‡ï¼š + 麥克風音é‡ï¼š </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="用這控制æ¢æ”¹è®ŠéŸ³é‡"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="用這個控制æ¢èª¿æ•´éº¥å…‹é¢¨éŸ³é‡"/> <text name="wait_text"> è«‹ç¨å€™ </text> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index 2ce310b2244755206af16492e10eeda7525fcf98..5ce5adf3f0ebc8509bbd6b148b1419ea41223ac7 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + 建製è¨ç½® [BUILD_CONFIG] + </string> <string name="AboutPosition"> ä½ çš„æ–¹ä½æ˜¯ [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地å€å:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) 第二人生URL:<nolink>[SLURL]</nolink> @@ -72,6 +75,9 @@ LLCEFLib/CEF版本:[LLCEFLIB_VERSION] <string name="ErrorFetchingServerReleaseNotesURL"> æ“·å–伺æœå™¨ç‰ˆæœ¬èªªæ˜Ž URL 時出錯。 </string> + <string name="BuildConfiguration"> + 建製è¨ç½® + </string> <string name="ProgressRestoring"> 回å˜ä¸... </string> @@ -1382,6 +1388,9 @@ http://secondlife.com/viewer-access-faq <string name="BodyPartsRightLeg"> å³è…¿ </string> + <string name="BodyPartsEnhancedSkeleton"> + 增強版骨架 + </string> <string name="GraphicsQualityLow"> 低 </string> @@ -1830,6 +1839,51 @@ http://secondlife.com/viewer-access-faq <string name="Avatar Center"> 化身ä¸å¿ƒ </string> + <string name="Left Ring Finger"> + 左無å指 + </string> + <string name="Right Ring Finger"> + å³ç„¡å指 + </string> + <string name="Tail Base"> + 尾巴基部 + </string> + <string name="Tail Tip"> + 尾巴末梢 + </string> + <string name="Left Wing"> + 左翼 + </string> + <string name="Right Wing"> + å³ç¿¼ + </string> + <string name="Jaw"> + é¡Ž + </string> + <string name="Alt Left Ear"> + 替代左耳 + </string> + <string name="Alt Right Ear"> + 替代å³è€³ + </string> + <string name="Alt Left Eye"> + 替代左眼 + </string> + <string name="Alt Right Eye"> + 替代å³çœ¼ + </string> + <string name="Tongue"> + 舌é + </string> + <string name="Groin"> + é¼ è¹Š + </string> + <string name="Left Hind Foot"> + 左後腳 + </string> + <string name="Right Hind Foot"> + å³å¾Œè…³ + </string> <string name="Invalid Attachment"> 無效的附接點 </string> @@ -2219,12 +2273,12 @@ http://secondlife.com/viewer-access-faq <string name="ATTACH_BELLY"> 腹部 </string> - <string name="ATTACH_RPEC"> - å³èƒ¸è‚Œ - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> 左胸肌 </string> + <string name="ATTACH_RIGHT_PEC"> + å³èƒ¸è‚Œ + </string> <string name="ATTACH_HUD_CENTER_2"> æ“¡é 顯示ä¸å¤® 2 </string> @@ -2255,6 +2309,51 @@ http://secondlife.com/viewer-access-faq <string name="ATTACH_AVATAR_CENTER"> 化身ä¸å¿ƒ </string> + <string name="ATTACH_LHAND_RING1"> + 左無å指 + </string> + <string name="ATTACH_RHAND_RING1"> + å³ç„¡å指 + </string> + <string name="ATTACH_TAIL_BASE"> + 尾巴基部 + </string> + <string name="ATTACH_TAIL_TIP"> + 尾巴末梢 + </string> + <string name="ATTACH_LWING"> + 左翼 + </string> + <string name="ATTACH_RWING"> + å³ç¿¼ + </string> + <string name="ATTACH_FACE_JAW"> + é¡Ž + </string> + <string name="ATTACH_FACE_LEAR"> + 替代左耳 + </string> + <string name="ATTACH_FACE_REAR"> + 替代å³è€³ + </string> + <string name="ATTACH_FACE_LEYE"> + 替代左眼 + </string> + <string name="ATTACH_FACE_REYE"> + 替代å³çœ¼ + </string> + <string name="ATTACH_FACE_TONGUE"> + 舌é + </string> + <string name="ATTACH_GROIN"> + é¼ è¹Š + </string> + <string name="ATTACH_HIND_LFOOT"> + 左後腳 + </string> + <string name="ATTACH_HIND_RFOOT"> + å³å¾Œè…³ + </string> <string name="CursorPos"> æ©«è¡Œ [LINE],縱列 [COLUMN] </string> @@ -4244,6 +4343,12 @@ http://secondlife.com/viewer-access-faq <string name="OfflineStatus"> 離線 </string> + <string name="not_online_msg"> + 使用者ä¸åœ¨ç·šä¸Š - 訊æ¯å°‡ç•™å˜ï¼Œç¨å¾Œå‚³éžã€‚ + </string> + <string name="not_online_inventory"> + 使用者ä¸åœ¨ç·šä¸Š - 收ç´å€å·²å„²å˜ã€‚ + </string> <string name="answered_call"> ä½ çš„é€šè©±å·²ç¶“æŽ¥é€š </string> diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..9b795f45fd878139c531a338f9c210a61605878d --- /dev/null +++ b/scripts/content_tools/anim_tool.py @@ -0,0 +1,602 @@ +#!runpy.sh + +"""\ + +This module contains tools for manipulating the .anim files supported +for Second Life animation upload. Note that this format is unrelated +to any non-Second Life formats of the same name. + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, 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$ +""" + +import sys +import os +import struct +import StringIO +import math +import argparse +import random +from lxml import etree + +U16MAX = 65535 +OOU16MAX = 1.0/(float)(U16MAX) + +LL_MAX_PELVIS_OFFSET = 5.0 + +class FilePacker(object): + def __init__(self): + self.data = StringIO.StringIO() + self.offset = 0 + + def write(self,filename): + f = open(filename,"wb") + f.write(self.data.getvalue()) + f.close() + + def pack(self,fmt,*args): + buf = struct.pack(fmt, *args) + self.offset += struct.calcsize(fmt) + self.data.write(buf) + + def pack_string(self,str,size=0): + buf = str + "\000" + if size and (len(buf) < size): + buf += "\000" * (size-len(buf)) + self.data.write(buf) + +class FileUnpacker(object): + def __init__(self, filename): + f = open(filename,"rb") + self.data = f.read() + self.offset = 0 + + def unpack(self,fmt): + result = struct.unpack_from(fmt, self.data, self.offset) + self.offset += struct.calcsize(fmt) + return result + + def unpack_string(self, size=0): + result = "" + i = 0 + while (self.data[self.offset+i] != "\000"): + result += self.data[self.offset+i] + i += 1 + i += 1 + if size: + # fixed-size field for the string + i = size + self.offset += i + return result + +# translated from the C++ version in lldefs.h +def llclamp(a, minval, maxval): + if a<minval: + return minval + if a>maxval: + return maxval + return a + +# translated from the C++ version in llquantize.h +def F32_to_U16(val, lower, upper): + val = llclamp(val, lower, upper); + # make sure that the value is positive and normalized to <0, 1> + val -= lower; + val /= (upper - lower); + + # return the U16 + return int(math.floor(val*U16MAX)) + +# translated from the C++ version in llquantize.h +def U16_to_F32(ival, lower, upper): + if ival < 0 or ival > U16MAX: + raise Exception("U16 out of range: "+ival) + val = ival*OOU16MAX + delta = (upper - lower) + val *= delta + val += lower + + max_error = delta*OOU16MAX; + + # make sure that zeroes come through as zero + if abs(val) < max_error: + val = 0.0 + return val; + +class BadFormat(Exception): + pass + +class RotKey(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.time_short, ) = fup.unpack("<H") + self.time = U16_to_F32(self.time_short, 0.0, anim.duration) + (x,y,z) = fup.unpack("<HHH") + self.rotation = [U16_to_F32(i, -1.0, 1.0) for i in (x,y,z)] + + def dump(self, f): + print >>f, " rot_key: t",self.time,"st",self.time_short,"rot",",".join([str(f) for f in self.rotation]) + + def pack(self, anim, fp): + if not hasattr(self,"time_short"): + self.time_short = F32_to_U16(self.time, 0.0, anim.duration) + fp.pack("<H",self.time_short) + (x,y,z) = [F32_to_U16(v, -1.0, 1.0) for v in self.rotation] + fp.pack("<HHH",x,y,z) + +class PosKey(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.time_short, ) = fup.unpack("<H") + self.time = U16_to_F32(self.time_short, 0.0, anim.duration) + (x,y,z) = fup.unpack("<HHH") + self.position = [U16_to_F32(i, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET) for i in (x,y,z)] + + def dump(self, f): + print >>f, " pos_key: t",self.time,"pos ",",".join([str(f) for f in self.position]) + + def pack(self, anim, fp): + if not hasattr(self,"time_short"): + self.time_short = F32_to_U16(self.time, 0.0, anim.duration) + fp.pack("<H",self.time_short) + (x,y,z) = [F32_to_U16(v, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET) for v in self.position] + fp.pack("<HHH",x,y,z) + +class Constraint(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.chain_length, self.constraint_type) = fup.unpack("<BB") + self.source_volume = fup.unpack_string(16) + self.source_offset = fup.unpack("<fff") + self.target_volume = fup.unpack_string(16) + self.target_offset = fup.unpack("<fff") + self.target_dir = fup.unpack("<fff") + fmt = "<ffff" + (self.ease_in_start, self.ease_in_stop, self.ease_out_start, self.ease_out_stop) = fup.unpack("<ffff") + + def pack(self, anim, fp): + fp.pack("<BB", self.chain_length, self.constraint_type) + fp.pack_string(self.source_volume, 16) + fp.pack("<fff", *self.source_offset) + fp.pack_string(self.target_volume, 16) + fp.pack("<fff", *self.target_offset) + fp.pack("<fff", *self.target_dir) + fp.pack("<ffff", self.ease_in_start, self.ease_in_stop, self.ease_out_start, self.ease_out_stop) + + def dump(self, f): + print >>f, " constraint:" + print >>f, " chain_length",self.chain_length + print >>f, " constraint_type",self.constraint_type + print >>f, " source_volume",self.source_volume + print >>f, " source_offset",self.source_offset + print >>f, " target_volume",self.target_volume + print >>f, " target_offset",self.target_offset + print >>f, " target_dir",self.target_dir + print >>f, " ease_in_start",self.ease_in_start + print >>f, " ease_in_stop",self.ease_in_stop + print >>f, " ease_out_start",self.ease_out_start + print >>f, " ease_out_stop",self.ease_out_stop + +class Constraints(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.num_constraints, ) = fup.unpack("<i") + self.constraints = [] + for i in xrange(self.num_constraints): + constraint = Constraint() + constraint.unpack(anim, fup) + self.constraints.append(constraint) + + def pack(self, anim, fp): + fp.pack("<i",self.num_constraints) + for c in self.constraints: + c.pack(anim,fp) + + def dump(self, f): + print >>f, "constraints:",self.num_constraints + for c in self.constraints: + c.dump(f) + +class PositionCurve(object): + def __init__(self): + self.num_pos_keys = 0 + self.keys = [] + + def is_static(self): + if self.keys: + k0 = self.keys[0] + for k in self.keys: + if k.position != k0.position: + return False + return True + + def unpack(self, anim, fup): + (self.num_pos_keys, ) = fup.unpack("<i") + self.keys = [] + for k in xrange(0,self.num_pos_keys): + pos_key = PosKey() + pos_key.unpack(anim, fup) + self.keys.append(pos_key) + + def pack(self, anim, fp): + fp.pack("<i",self.num_pos_keys) + for k in self.keys: + k.pack(anim, fp) + + def dump(self, f): + print >>f, " position_curve:" + print >>f, " num_pos_keys", self.num_pos_keys + for k in xrange(0,self.num_pos_keys): + self.keys[k].dump(f) + +class RotationCurve(object): + def __init__(self): + self.num_rot_keys = 0 + self.keys = [] + + def is_static(self): + if self.keys: + k0 = self.keys[0] + for k in self.keys: + if k.rotation != k0.rotation: + return False + return True + + def unpack(self, anim, fup): + (self.num_rot_keys, ) = fup.unpack("<i") + self.keys = [] + for k in xrange(0,self.num_rot_keys): + rot_key = RotKey() + rot_key.unpack(anim, fup) + self.keys.append(rot_key) + + def pack(self, anim, fp): + fp.pack("<i",self.num_rot_keys) + for k in self.keys: + k.pack(anim, fp) + + def dump(self, f): + print >>f, " rotation_curve:" + print >>f, " num_rot_keys", self.num_rot_keys + for k in xrange(0,self.num_rot_keys): + self.keys[k].dump(f) + +class JointInfo(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + self.joint_name = fup.unpack_string() + (self.joint_priority, ) = fup.unpack("<i") + self.rotation_curve = RotationCurve() + self.rotation_curve.unpack(anim, fup) + self.position_curve = PositionCurve() + self.position_curve.unpack(anim, fup) + + def pack(self, anim, fp): + fp.pack_string(self.joint_name) + fp.pack("<i", self.joint_priority) + self.rotation_curve.pack(anim, fp) + self.position_curve.pack(anim, fp) + + def dump(self, f): + print >>f, "joint:" + print >>f, " joint_name:",self.joint_name + print >>f, " joint_priority:",self.joint_priority + self.rotation_curve.dump(f) + self.position_curve.dump(f) + +class Anim(object): + def __init__(self, filename=None): + if filename: + self.read(filename) + + def read(self, filename): + fup = FileUnpacker(filename) + self.unpack(fup) + + # various validity checks could be added - see LLKeyframeMotion::deserialize() + def unpack(self,fup): + (self.version, self.sub_version, self.base_priority, self.duration) = fup.unpack("@HHhf") + + if self.version == 0 and self.sub_version == 1: + self.old_version = True + raise BadFormat("old version not supported") + elif self.version == 1 and self.sub_version == 0: + self.old_version = False + else: + raise BadFormat("Bad combination of version, sub_version: %d %d" % (self.version, self.sub_version)) + + self.emote_name = fup.unpack_string() + + (self.loop_in_point, self.loop_out_point, self.loop, self.ease_in_duration, self.ease_out_duration, self.hand_pose, self.num_joints) = fup.unpack("@ffiffII") + + self.joints = [] + for j in xrange(0,self.num_joints): + joint_info = JointInfo() + joint_info.unpack(self, fup) + self.joints.append(joint_info) + print "unpacked joint",joint_info.joint_name + self.constraints = Constraints() + self.constraints.unpack(self, fup) + self.data = fup.data + + def pack(self, fp): + fp.pack("@HHhf", self.version, self.sub_version, self.base_priority, self.duration) + fp.pack_string(self.emote_name, 0) + fp.pack("@ffiffII", self.loop_in_point, self.loop_out_point, self.loop, self.ease_in_duration, self.ease_out_duration, self.hand_pose, self.num_joints) + for j in self.joints: + j.pack(anim, fp) + self.constraints.pack(anim, fp) + + def dump(self, filename="-"): + if filename=="-": + f = sys.stdout + else: + f = open(filename,"w") + print >>f, "versions: ", self.version, self.sub_version + print >>f, "base_priority: ", self.base_priority + print >>f, "duration: ", self.duration + print >>f, "emote_name: ", self.emote_name + print >>f, "loop_in_point: ", self.loop_in_point + print >>f, "loop_out_point: ", self.loop_out_point + print >>f, "loop: ", self.loop + print >>f, "ease_in_duration: ", self.ease_in_duration + print >>f, "ease_out_duration: ", self.ease_out_duration + print >>f, "hand_pose", self.hand_pose + print >>f, "num_joints", self.num_joints + for j in self.joints: + j.dump(f) + self.constraints.dump(f) + + def write(self, filename): + fp = FilePacker() + self.pack(fp) + fp.write(filename) + + def write_src_data(self, filename): + print "write file",filename + f = open(filename,"wb") + f.write(self.data) + f.close() + + def find_joint(self, name): + joints = [j for j in self.joints if j.joint_name == name] + if joints: + return joints[0] + else: + return None + + def add_joint(self, name, priority): + if not self.find_joint(name): + j = JointInfo() + j.joint_name = name + j.joint_priority = priority + j.rotation_curve = RotationCurve() + j.position_curve = PositionCurve() + self.joints.append(j) + self.num_joints = len(self.joints) + + def delete_joint(self, name): + j = self.find_joint(name) + if j: + anim.joints.remove(j) + anim.num_joints = len(self.joints) + + def summary(self): + nj = len(self.joints) + nz = len([j for j in self.joints if j.joint_priority > 0]) + nstatic = len([j for j in self.joints if j.rotation_curve.is_static() and j.position_curve.is_static()]) + print "summary: %d joints, non-zero priority %d, static %d" % (nj, nz, nstatic) + + def add_pos(self, joint_names, positions): + js = [joint for joint in self.joints if joint.joint_name in joint_names] + for j in js: + if args.verbose: + print "adding positions",j.joint_name,positions + j.joint_priority = 4 + j.position_curve.num_pos_keys = len(positions) + j.position_curve.keys = [] + for i,pos in enumerate(positions): + key = PosKey() + key.time = self.duration * i / (len(positions) - 1) + key.time_short = F32_to_U16(key.time, 0.0, self.duration) + key.position = pos + j.position_curve.keys.append(key) + + def add_rot(self, joint_names, rotations): + js = [joint for joint in self.joints if joint.joint_name in joint_names] + for j in js: + print "adding rotations",j.joint_name + j.joint_priority = 4 + j.rotation_curve.num_rot_keys = len(rotations) + j.rotation_curve.keys = [] + for i,pos in enumerate(rotations): + key = RotKey() + key.time = self.duration * i / (len(rotations) - 1) + key.time_short = F32_to_U16(key.time, 0.0, self.duration) + key.rotation = pos + j.rotation_curve.keys.append(key) + +def twistify(anim, joint_names, rot1, rot2): + js = [joint for joint in anim.joints if joint.joint_name in joint_names] + for j in js: + print "twisting",j.joint_name + print j.rotation_curve.num_rot_keys + j.joint_priority = 4 + j.rotation_curve.num_rot_keys = 2 + j.rotation_curve.keys = [] + key1 = RotKey() + key1.time_short = 0 + key1.time = U16_to_F32(key1.time_short, 0.0, anim.duration) + key1.rotation = rot1 + key2 = RotKey() + key2.time_short = U16MAX + key2.time = U16_to_F32(key2.time_short, 0.0, anim.duration) + key2.rotation = rot2 + j.rotation_curve.keys.append(key1) + j.rotation_curve.keys.append(key2) + +def float_triple(arg): + vals = arg.split() + if len(vals)==3: + return [float(x) for x in vals] + else: + raise Exception("arg %s does not resolve to a float triple" % arg) + +def get_joint_by_name(tree,name): + if tree is None: + return None + matches = [elt for elt in tree.getroot().iter() if \ + elt.get("name")==name and elt.tag in ["bone", "collision_volume", "attachment_point"]] + if len(matches)==1: + return matches[0] + elif len(matches)>1: + print "multiple matches for name",name + return None + else: + return None + +def get_elt_pos(elt): + if elt.get("pos"): + return float_triple(elt.get("pos")) + elif elt.get("position"): + return float_triple(elt.get("position")) + else: + return (0.0, 0.0, 0.0) + +def resolve_joints(names, skel_tree, lad_tree): + print "resolve joints, no_hud is",args.no_hud + if skel_tree and lad_tree: + all_elts = [elt for elt in skel_tree.getroot().iter()] + all_elts.extend([elt for elt in lad_tree.getroot().iter()]) + matches = [] + for elt in all_elts: + if elt.get("name") is None: + continue + print elt.get("name"),"hud",elt.get("hud") + if args.no_hud and elt.get("hud"): + print "skipping hud joint", elt.get("name") + continue + if elt.get("name") in names or elt.tag in names: + matches.append(elt.get("name")) + return list(set(matches)) + else: + return names + +if __name__ == "__main__": + + # default search location for config files is defined relative to + # the script location; assuming they live in the same viewer repo + pathname = os.path.dirname(sys.argv[0]) + path_to_skel = os.path.join(os.path.abspath(pathname),"..","..","indra","newview","character") + + parser = argparse.ArgumentParser(description="process SL animations") + parser.add_argument("--verbose", help="verbose flag", action="store_true") + parser.add_argument("--dump", help="dump to specified file") + parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+") + parser.add_argument("--rand_pos", help="request random positions", action="store_true") + parser.add_argument("--reset_pos", help="request original positions", action="store_true") + parser.add_argument("--pos", help="specify sequence of positions", type=float_triple, nargs="+") + parser.add_argument("--num_pos", help="number of positions to create", type=int, default=2) + parser.add_argument("--delete_joints", help="specify joints to be deleted", nargs="+") + parser.add_argument("--joints", help="specify joints to be added or modified", nargs="+") + parser.add_argument("--summary", help="print summary of the output animation", action="store_true") + parser.add_argument("--skel", help="name of the avatar_skeleton file", default= os.path.join(path_to_skel,"avatar_skeleton.xml")) + parser.add_argument("--lad", help="name of the avatar_lad file", default= os.path.join(path_to_skel,"avatar_lad.xml")) + parser.add_argument("--set_version", nargs=2, type=int, help="set version and sub-version to specified values") + parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true") + parser.add_argument("infilename", help="name of a .anim file to input") + parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output") + args = parser.parse_args() + + print "anim_tool.py: " + " ".join(sys.argv) + print "dump is", args.dump + print "infilename",args.infilename,"outfilename",args.outfilename + print "rot",args.rot + print "pos",args.pos + print "joints",args.joints + + try: + anim = Anim(args.infilename) + skel_tree = None + lad_tree = None + joints = [] + if args.skel: + skel_tree = etree.parse(args.skel) + if skel_tree is None: + print "failed to parse",args.skel + exit(1) + if args.lad: + lad_tree = etree.parse(args.lad) + if lad_tree is None: + print "failed to parse",args.lad + exit(1) + if args.joints: + joints = resolve_joints(args.joints, skel_tree, lad_tree) + if args.verbose: + print "joints resolved to",joints + for name in joints: + anim.add_joint(name,0) + if args.delete_joints: + for name in args.delete_joints: + anim.delete_joint(name) + if joints and args.rot: + anim.add_rot(joints, args.rot) + if joints and args.pos: + anim.add_pos(joints, args.pos) + if joints and args.rand_pos: + for joint in joints: + pos_array = list(tuple(random.uniform(-1,1) for i in xrange(3)) for j in xrange(args.num_pos)) + pos_array.append(pos_array[0]) + anim.add_pos([joint], pos_array) + if joints and args.reset_pos: + for joint in joints: + elt = get_joint_by_name(skel_tree,joint) + if elt is None: + elt = get_joint_by_name(lad_tree,joint) + if elt is not None: + pos_array = [] + pos_array.append(get_elt_pos(elt)) + pos_array.append(pos_array[0]) + anim.add_pos([joint], pos_array) + else: + print "no elt or no pos data for",joint + if args.set_version: + anim.version = args.set_version[0] + anim.sub_version = args.set_version[1] + if args.dump: + anim.dump(args.dump) + if args.summary: + anim.summary() + if args.outfilename: + anim.write(args.outfilename) + except: + raise + diff --git a/scripts/content_tools/arche_tool.py b/scripts/content_tools/arche_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..23c96fc64ef40b605dbeb19a3dc9a09434986e3d --- /dev/null +++ b/scripts/content_tools/arche_tool.py @@ -0,0 +1,93 @@ +#!runpy.sh + +"""\ + +This module contains tools for comparing files output by LLVOAvatar::dumpArchetypeXML + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, 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$ +""" + +import argparse +from lxml import etree +from itertools import chain + +def node_key(e): + if e.tag == "param": + return e.tag + " " + e.get("id") + if e.tag == "texture": + return e.tag + " " + e.get("te") + if e.get("name"): + return e.tag + " " + e.get("name") + return None + +def compare_matched_nodes(key,items,summary): + tags = list(set([e.tag for e in items])) + if len(tags) != 1: + print "different tag types for key",key + summary.setdefault("tag_mismatch",0) + summary["tag_mismatch"] += 1 + return + all_attrib = list(set(chain.from_iterable([e.attrib.keys() for e in items]))) + #print key,"all_attrib",all_attrib + for attr in all_attrib: + vals = [e.get(attr) for e in items] + #print "key",key,"attr",attr,"vals",vals + if len(set(vals)) != 1: + print key,"- attr",attr,"multiple values",vals + summary.setdefault("attr",{}) + summary["attr"].setdefault(attr,0) + summary["attr"][attr] += 1 + +def compare_trees(file_trees): + print "compare_trees" + summary = {} + all_keys = list(set([node_key(e) for tree in file_trees for e in tree.getroot().iter() if node_key(e)])) + #print "keys",all_keys + tree_nodes = [] + for i,tree in enumerate(file_trees): + nodes = dict((node_key(e),e) for e in tree.getroot().iter() if node_key(e)) + tree_nodes.append(nodes) + for key in sorted(all_keys): + items = [] + for nodes in tree_nodes: + if not key in nodes: + print "file",i,"missing item for key",key + summary.setdefault("missing",0) + summary["missing"] += 1 + else: + items.append(nodes[key]) + compare_matched_nodes(key,items,summary) + print "Summary:" + print summary + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description="compare avatar XML archetype files") + parser.add_argument("--verbose", help="verbose flag", action="store_true") + parser.add_argument("files", nargs="+", help="name of one or more archtype files") + args = parser.parse_args() + + + print "files",args.files + file_trees = [etree.parse(filename) for filename in args.files] + compare_trees(file_trees) diff --git a/scripts/content_tools/dae_tool.py b/scripts/content_tools/dae_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..823f69cb854d1123cf1cb4a17c755e47ed78e3f6 --- /dev/null +++ b/scripts/content_tools/dae_tool.py @@ -0,0 +1,119 @@ +#!runpy.sh + +"""\ + +This module contains tools for manipulating collada files + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, 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$ +""" + +import argparse +import random + +# Need to pip install numpy and pycollada +import numpy as np +from collada import * +from lxml import etree + +def mesh_summary(mesh): + print "scenes",mesh.scenes + for scene in mesh.scenes: + print "scene",scene + for node in scene.nodes: + print "node",node + +def mesh_lock_offsets(tree, joints): + print "mesh_lock_offsets",tree,joints + for joint_node in tree.iter(): + if "node" not in joint_node.tag: + continue + if joint_node.get("type") != "JOINT": + continue + if joint_node.get("name") in joints or "bone" in joints: + for matrix_node in list(joint_node): + if "matrix" in matrix_node.tag: + floats = [float(x) for x in matrix_node.text.split()] + if len(floats) == 16: + floats[3] += 0.0001 + floats[7] += 0.0001 + floats[11] += 0.0001 + matrix_node.text = " ".join([str(f) for f in floats]) + print joint_node.get("name"),matrix_node.tag,"text",matrix_node.text,len(floats),floats + + +def mesh_random_offsets(tree, joints): + print "mesh_random_offsets",tree,joints + for joint_node in tree.iter(): + if "node" not in joint_node.tag: + continue + if joint_node.get("type") != "JOINT": + continue + if not joint_node.get("name"): + continue + if joint_node.get("name") in joints or "bone" in joints: + for matrix_node in list(joint_node): + if "matrix" in matrix_node.tag: + floats = [float(x) for x in matrix_node.text.split()] + print "randomizing",floats + if len(floats) == 16: + floats[3] += random.uniform(-1.0,1.0) + floats[7] += random.uniform(-1.0,1.0) + floats[11] += random.uniform(-1.0,1.0) + matrix_node.text = " ".join([str(f) for f in floats]) + print joint_node.get("name"),matrix_node.tag,"text",matrix_node.text,len(floats),floats + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="process SL animations") + parser.add_argument("--verbose", action="store_true",help="verbose flag") + parser.add_argument("infilename", help="name of a collada (dae) file to input") + parser.add_argument("outfilename", nargs="?", help="name of a collada (dae) file to output", default = None) + parser.add_argument("--lock_offsets", nargs="+", help="tweak position of listed joints to lock their offsets") + parser.add_argument("--random_offsets", nargs="+", help="random offset position for listed joints") + parser.add_argument("--summary", action="store_true", help="print summary info about input file") + args = parser.parse_args() + + mesh = None + tree = None + + if args.infilename: + print "reading",args.infilename + mesh = Collada(args.infilename) + tree = etree.parse(args.infilename) + + if args.summary: + print "summarizing",args.infilename + mesh_summary(mesh) + + if args.lock_offsets: + print "locking offsets for",args.lock_offsets + mesh_lock_offsets(tree, args.lock_offsets) + + if args.random_offsets: + print "adding random offsets for",args.random_offsets + mesh_random_offsets(tree, args.random_offsets) + + if args.outfilename: + print "writing",args.outfilename + f = open(args.outfilename,"w") + print >>f, etree.tostring(tree, pretty_print=True) #need update to get: , short_empty_elements=True) + diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..26f63326f1d67822872c0405e746e22ef2df6691 --- /dev/null +++ b/scripts/content_tools/skel_tool.py @@ -0,0 +1,503 @@ +#!runpy.sh + +"""\ + +This module contains tools for manipulating and validating the avatar skeleton file. + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, 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$ +""" + +import argparse + +from lxml import etree + +def get_joint_names(tree): + joints = [element.get('name') for element in tree.getroot().iter() if element.tag in ['bone','collision_volume']] + print "joints:",joints + return joints + +def get_aliases(tree): + aliases = {} + alroot = tree.getroot() + for element in alroot.iter(): + for key in element.keys(): + if key == 'aliases': + name = element.get('name') + val = element.get('aliases') + aliases[name] = val + return aliases + +def fix_name(element): + pass + +def enforce_precision_rules(element): + pass + +def float_tuple(str, n=3): + try: + result = tuple(float(e) for e in str.split()) + if len(result)==n: + return result + else: + print "tuple length wrong:", str,"gave",result,"wanted len",n,"got len",len(result) + raise Exception() + except: + print "convert failed for:",str + raise + +def check_symmetry(name, field, vec1, vec2): + if vec1[0] != vec2[0]: + print name,field,"x match fail" + if vec1[1] != -vec2[1]: + print name,field,"y mirror image fail" + if vec1[2] != vec2[2]: + print name,field,"z match fail" + +def enforce_symmetry(tree, element, field, fix=False): + name = element.get("name") + if not name: + return + if "Right" in name: + left_name = name.replace("Right","Left") + left_element = get_element_by_name(tree, left_name) + pos = element.get(field) + left_pos = left_element.get(field) + pos_tuple = float_tuple(pos) + left_pos_tuple = float_tuple(left_pos) + check_symmetry(name,field,pos_tuple,left_pos_tuple) + +def get_element_by_name(tree,name): + if tree is None: + return None + matches = [elt for elt in tree.getroot().iter() if elt.get("name")==name] + if len(matches)==1: + return matches[0] + elif len(matches)>1: + print "multiple matches for name",name + return None + else: + return None + +def list_skel_tree(tree): + for element in tree.getroot().iter(): + if element.tag == "bone": + print element.get("name"),"-",element.get("support") + +def validate_child_order(tree, ogtree, fix=False): + unfixable = 0 + + #print "validate_child_order am failing for NO RAISIN!" + #unfixable += 1 + + tofix = set() + for element in tree.getroot().iter(): + if element.tag != "bone": + continue + og_element = get_element_by_name(ogtree,element.get("name")) + if og_element is not None: + for echild,ochild in zip(list(element),list(og_element)): + if echild.get("name") != ochild.get("name"): + print "Child ordering error, parent",element.get("name"),echild.get("name"),"vs",ochild.get("name") + if fix: + tofix.add(element.get("name")) + children = {} + for name in tofix: + print "FIX",name + element = get_element_by_name(tree,name) + og_element = get_element_by_name(ogtree,name) + children = [] + # add children matching the original joints first, in the same order + for og_elt in list(og_element): + elt = get_element_by_name(tree,og_elt.get("name")) + if elt is not None: + children.append(elt) + print "b:",elt.get("name") + else: + print "b missing:",og_elt.get("name") + # then add children that are not present in the original joints + for elt in list(element): + og_elt = get_element_by_name(ogtree,elt.get("name")) + if og_elt is None: + children.append(elt) + print "e:",elt.get("name") + # if we've done this right, we have a rearranged list of the same length + if len(children)!=len(element): + print "children",[e.get("name") for e in children] + print "element",[e.get("name") for e in element] + print "children changes for",name,", cannot reconcile" + else: + element[:] = children + + return unfixable + +# Checklist for the final file, started from SL-276: +# - new "end" attribute on all bones +# - new "connected" attribute on all bones +# - new "support" tag on all bones and CVs +# - aliases where appropriate for backward compatibility. rFoot and lFoot associated with mAnkle bones (not mFoot bones) +# - correct counts of bones and collision volumes in header +# - check all comments +# - old fields of old bones and CVs should be identical to their previous values. +# - old bones and CVs should retain their previous ordering under their parent, with new joints going later in any given child list +# - corresponding right and left joints should be mirror symmetric. +# - childless elements should be in short form (<bone /> instead of <bone></bone>) +# - digits of precision should be consistent (again, except for old joints) +# - new bones should have pos, pivot the same +def validate_skel_tree(tree, ogtree, reftree, fix=False): + print "validate_skel_tree" + (num_bones,num_cvs) = (0,0) + unfixable = 0 + defaults = {"connected": "false", + "group": "Face" + } + for element in tree.getroot().iter(): + og_element = get_element_by_name(ogtree,element.get("name")) + ref_element = get_element_by_name(reftree,element.get("name")) + # Preserve values from og_file: + for f in ["pos","rot","scale","pivot"]: + if og_element is not None and og_element.get(f) and (str(element.get(f)) != str(og_element.get(f))): + print element.get("name"),"field",f,"has changed:",og_element.get(f),"!=",element.get(f) + if fix: + element.set(f, og_element.get(f)) + + # Pick up any other fields that we can from ogtree and reftree + fields = [] + if element.tag in ["bone","collision_volume"]: + fields = ["support","group"] + if element.tag == 'bone': + fields.extend(["end","connected"]) + for f in fields: + if not element.get(f): + print element.get("name"),"missing required field",f + if fix: + if og_element is not None and og_element.get(f): + print "fix from ogtree" + element.set(f,og_element.get(f)) + elif ref_element is not None and ref_element.get(f): + print "fix from reftree" + element.set(f,ref_element.get(f)) + else: + if f in defaults: + print "fix by using default value",f,"=",defaults[f] + element.set(f,defaults[f]) + elif f == "support": + if og_element is not None: + element.set(f,"base") + else: + element.set(f,"extended") + else: + print "unfixable:",element.get("name"),"no value for field",f + unfixable += 1 + + fix_name(element) + enforce_precision_rules(element) + for field in ["pos","pivot"]: + enforce_symmetry(tree, element, field, fix) + if element.get("support")=="extended": + if element.get("pos") != element.get("pivot"): + print "extended joint",element.get("name"),"has mismatched pos, pivot" + + + if element.tag == "linden_skeleton": + num_bones = int(element.get("num_bones")) + num_cvs = int(element.get("num_collision_volumes")) + all_bones = [e for e in tree.getroot().iter() if e.tag=="bone"] + all_cvs = [e for e in tree.getroot().iter() if e.tag=="collision_volume"] + if num_bones != len(all_bones): + print "wrong bone count, expected",len(all_bones),"got",num_bones + if fix: + element.set("num_bones", str(len(all_bones))) + if num_cvs != len(all_cvs): + print "wrong cv count, expected",len(all_cvs),"got",num_cvs + if fix: + element.set("num_collision_volumes", str(len(all_cvs))) + + print "skipping child order code" + #unfixable += validate_child_order(tree, ogtree, fix) + + if fix and (unfixable > 0): + print "BAD FILE:", unfixable,"errs could not be fixed" + + +def slider_info(ladtree,skeltree): + for param in ladtree.iter("param"): + for skel_param in param.iter("param_skeleton"): + bones = [b for b in skel_param.iter("bone")] + if bones: + print "param",param.get("name"),"id",param.get("id") + value_min = float(param.get("value_min")) + value_max = float(param.get("value_max")) + neutral = 100.0 * (0.0-value_min)/(value_max-value_min) + print " neutral",neutral + for b in bones: + scale = float_tuple(b.get("scale","0 0 0")) + offset = float_tuple(b.get("offset","0 0 0")) + print " bone", b.get("name"), "scale", scale, "offset", offset + scale_min = [value_min * s for s in scale] + scale_max = [value_max * s for s in scale] + offset_min = [value_min * t for t in offset] + offset_max = [value_max * t for t in offset] + if (scale_min != scale_max): + print " Scale MinX", scale_min[0] + print " Scale MinY", scale_min[1] + print " Scale MinZ", scale_min[2] + print " Scale MaxX", scale_max[0] + print " Scale MaxY", scale_max[1] + print " Scale MaxZ", scale_max[2] + if (offset_min != offset_max): + print " Offset MinX", offset_min[0] + print " Offset MinY", offset_min[1] + print " Offset MinZ", offset_min[2] + print " Offset MaxX", offset_max[0] + print " Offset MaxY", offset_max[1] + print " Offset MaxZ", offset_max[2] + +# Check contents of avatar_lad file relative to a specified skeleton +def validate_lad_tree(ladtree,skeltree,orig_ladtree): + print "validate_lad_tree" + bone_names = [elt.get("name") for elt in skeltree.iter("bone")] + bone_names.append("mScreen") + bone_names.append("mRoot") + cv_names = [elt.get("name") for elt in skeltree.iter("collision_volume")] + #print "bones\n ","\n ".join(sorted(bone_names)) + #print "cvs\n ","\n ".join(sorted(cv_names)) + for att in ladtree.iter("attachment_point"): + att_name = att.get("name") + #print "attachment",att_name + joint_name = att.get("joint") + if not joint_name in bone_names: + print "att",att_name,"linked to invalid joint",joint_name + for skel_param in ladtree.iter("param_skeleton"): + skel_param_id = skel_param.get("id") + skel_param_name = skel_param.get("name") + #if not skel_param_name and not skel_param_id: + # print "strange skel_param" + # print etree.tostring(skel_param) + # for k,v in skel_param.attrib.iteritems(): + # print k,"->",v + for bone in skel_param.iter("bone"): + bone_name = bone.get("name") + if not bone_name in bone_names: + print "skel param references invalid bone",bone_name + print etree.tostring(bone) + bone_scale = float_tuple(bone.get("scale","0 0 0")) + bone_offset = float_tuple(bone.get("offset","0 0 0")) + param = bone.getparent().getparent() + if bone_scale==(0, 0, 0) and bone_offset==(0, 0, 0): + print "no-op bone",bone_name,"in param",param.get("id","-1") + # check symmetry of sliders + if "Right" in bone.get("name"): + left_name = bone_name.replace("Right","Left") + left_bone = None + for b in skel_param.iter("bone"): + if b.get("name")==left_name: + left_bone = b + if left_bone is None: + print "left_bone not found",left_name,"in",param.get("id","-1") + else: + left_scale = float_tuple(left_bone.get("scale","0 0 0")) + left_offset = float_tuple(left_bone.get("offset","0 0 0")) + if left_scale != bone_scale: + print "scale mismatch between",bone_name,"and",left_name,"in param",param.get("id","-1") + param_id = int(param.get("id","-1")) + if param_id in [661]: # shear + expected_offset = tuple([bone_offset[0],bone_offset[1],-bone_offset[2]]) + elif param_id in [30656, 31663, 32663]: # shift + expected_offset = bone_offset + else: + expected_offset = tuple([bone_offset[0],-bone_offset[1],bone_offset[2]]) + if left_offset != expected_offset: + print "offset mismatch between",bone_name,"and",left_name,"in param",param.get("id","-1") + + drivers = {} + for driven_param in ladtree.iter("driven"): + driver = driven_param.getparent().getparent() + driven_id = driven_param.get("id") + driver_id = driver.get("id") + actual_param = next(param for param in ladtree.iter("param") if param.get("id")==driven_id) + if not driven_id in drivers: + drivers[driven_id] = set() + drivers[driven_id].add(driver_id) + if (actual_param.get("value_min") != driver.get("value_min") or \ + actual_param.get("value_max") != driver.get("value_max")): + if args.verbose: + print "MISMATCH min max:",driver.get("id"),"drives",driven_param.get("id"),"min",driver.get("value_min"),actual_param.get("value_min"),"max",driver.get("value_max"),actual_param.get("value_max") + + for driven_id in drivers: + dset = drivers[driven_id] + if len(dset) != 1: + print "driven_id",driven_id,"has multiple drivers",dset + else: + if args.verbose: + print "driven_id",driven_id,"has one driver",dset + if orig_ladtree: + # make sure expected message format is unchanged + orig_message_params_by_id = dict((int(param.get("id")),param) for param in orig_ladtree.iter("param") if param.get("group") in ["0","3"]) + orig_message_ids = sorted(orig_message_params_by_id.keys()) + #print "orig_message_ids",orig_message_ids + message_params_by_id = dict((int(param.get("id")),param) for param in ladtree.iter("param") if param.get("group") in ["0","3"]) + message_ids = sorted(message_params_by_id.keys()) + #print "message_ids",message_ids + if (set(message_ids) != set(orig_message_ids)): + print "mismatch in message ids!" + print "added",set(message_ids) - set(orig_message_ids) + print "removed",set(orig_message_ids) - set(message_ids) + else: + print "message ids OK" + +def remove_joint_by_name(tree, name): + print "remove joint:",name + elt = get_element_by_name(tree,name) + while elt is not None: + children = list(elt) + parent = elt.getparent() + print "graft",[e.get("name") for e in children],"into",parent.get("name") + print "remove",elt.get("name") + #parent_children = list(parent) + loc = parent.index(elt) + parent[loc:loc+1] = children + elt[:] = [] + print "parent now:",[e.get("name") for e in list(parent)] + elt = get_element_by_name(tree,name) + +def compare_skel_trees(atree,btree): + diffs = {} + realdiffs = {} + a_missing = set() + b_missing = set() + a_names = set(e.get("name") for e in atree.getroot().iter() if e.get("name")) + b_names = set(e.get("name") for e in btree.getroot().iter() if e.get("name")) + print "a_names\n ",str("\n ").join(sorted(list(a_names))) + print + print "b_names\n ","\n ".join(sorted(list(b_names))) + all_names = set.union(a_names,b_names) + for name in all_names: + if not name: + continue + a_element = get_element_by_name(atree,name) + b_element = get_element_by_name(btree,name) + if a_element is None or b_element is None: + print "something not found for",name,a_element,b_element + if a_element is not None and b_element is not None: + all_attrib = set.union(set(a_element.attrib.keys()),set(b_element.attrib.keys())) + print name,all_attrib + for att in all_attrib: + if a_element.get(att) != b_element.get(att): + if not att in diffs: + diffs[att] = set() + diffs[att].add(name) + print "tuples",name,att,float_tuple(a_element.get(att)),float_tuple(b_element.get(att)) + if float_tuple(a_element.get(att)) != float_tuple(b_element.get(att)): + print "diff in",name,att + if not att in realdiffs: + realdiffs[att] = set() + realdiffs[att].add(name) + for att in diffs: + print "Differences in",att + for name in sorted(diffs[att]): + print " ",name + for att in realdiffs: + print "Real differences in",att + for name in sorted(diffs[att]): + print " ",name + a_missing = b_names.difference(a_names) + b_missing = a_names.difference(b_names) + if len(a_missing) or len(b_missing): + print "Missing from comparison" + for name in a_missing: + print " ",name + print "Missing from infile" + for name in b_missing: + print " ",name + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description="process SL avatar_skeleton/avatar_lad files") + parser.add_argument("--verbose", action="store_true",help="verbose flag") + parser.add_argument("--ogfile", help="specify file containing base bones", default="avatar_skeleton_orig.xml") + parser.add_argument("--ref_file", help="specify another file containing replacements for missing fields") + parser.add_argument("--lad_file", help="specify avatar_lad file to check", default="avatar_lad.xml") + parser.add_argument("--orig_lad_file", help="specify avatar_lad file to compare to", default="avatar_lad_orig.xml") + parser.add_argument("--aliases", help="specify file containing bone aliases") + parser.add_argument("--validate", action="store_true", help="check specified input file for validity") + parser.add_argument("--fix", action="store_true", help="try to correct errors") + parser.add_argument("--remove", nargs="+", help="remove specified joints") + parser.add_argument("--list", action="store_true", help="list joint names") + parser.add_argument("--compare", help="alternate skeleton file to compare") + parser.add_argument("--slider_info", help="information about the lad file sliders and affected bones", action="store_true") + parser.add_argument("infilename", nargs="?", help="name of a skel .xml file to input", default="avatar_skeleton.xml") + parser.add_argument("outfilename", nargs="?", help="name of a skel .xml file to output") + args = parser.parse_args() + + tree = etree.parse(args.infilename) + + aliases = {} + if args.aliases: + altree = etree.parse(args.aliases) + aliases = get_aliases(altree) + + # Parse input files + ogtree = None + reftree = None + ladtree = None + orig_ladtree = None + + if args.ogfile: + ogtree = etree.parse(args.ogfile) + + if args.ref_file: + reftree = etree.parse(args.ref_file) + + if args.lad_file: + ladtree = etree.parse(args.lad_file) + + if args.orig_lad_file: + orig_ladtree = etree.parse(args.orig_lad_file) + + if args.remove: + for name in args.remove: + remove_joint_by_name(tree,name) + + # Do processing + if args.validate and ogtree: + validate_skel_tree(tree, ogtree, reftree) + + if args.validate and ladtree: + validate_lad_tree(ladtree, tree, orig_ladtree) + + if args.fix and ogtree: + validate_skel_tree(tree, ogtree, reftree, True) + + if args.list and tree: + list_skel_tree(tree) + + if args.compare and tree: + compare_tree = etree.parse(args.compare) + compare_skel_trees(compare_tree,tree) + + if ladtree and tree and args.slider_info: + slider_info(ladtree,tree) + + if args.outfilename: + f = open(args.outfilename,"w") + print >>f, etree.tostring(tree, pretty_print=True) #need update to get: , short_empty_elements=True) +