Merge bento-box
commit
be6ce75a96
|
|
@ -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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
private:
|
||||
S32 mNumBones;
|
||||
S32 mNumCollisionVolumes;
|
||||
LLAvatarAppearance::joint_alias_map_t mJointAliasMap;
|
||||
typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
|
||||
bone_info_list_t mBoneInfoList;
|
||||
};
|
||||
|
|
@ -333,36 +338,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;
|
||||
|
|
@ -375,16 +393,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);
|
||||
|
|
@ -557,7 +578,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;
|
||||
|
|
@ -573,6 +594,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);
|
||||
|
|
@ -604,6 +631,8 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
|
|||
joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
|
||||
info->mRot.mV[VZ], LLQuaternion::XYZ));
|
||||
joint->setScale(info->mScale);
|
||||
joint->setSupport(info->mSupport);
|
||||
joint->setEnd(info->mEnd);
|
||||
|
||||
if (info->mIsJoint)
|
||||
{
|
||||
|
|
@ -636,10 +665,7 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( S32 num )
|
|||
{
|
||||
clearSkeleton();
|
||||
|
||||
for(S32 joint_num = 0; joint_num < num; joint_num++)
|
||||
{
|
||||
mSkeleton.push_back(createAvatarJoint(joint_num));
|
||||
}
|
||||
mSkeleton = avatar_joint_list_t(num,NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -650,6 +676,7 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( S32 num )
|
|||
//-----------------------------------------------------------------------------
|
||||
BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
|
||||
{
|
||||
LL_DEBUGS("BVH") << "numBones " << info->mNumBones << " numCollisionVolumes " << info->mNumCollisionVolumes << LL_ENDL;
|
||||
//-------------------------------------------------------------------------
|
||||
// allocate joints
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
@ -676,8 +703,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;
|
||||
|
|
@ -1261,6 +1288,10 @@ LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num )
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!mSkeleton[num])
|
||||
{
|
||||
mSkeleton[num] = createAvatarJoint(num);
|
||||
}
|
||||
return mSkeleton[num];
|
||||
}
|
||||
|
||||
|
|
@ -1532,6 +1563,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"))
|
||||
{
|
||||
|
|
@ -1569,6 +1603,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");
|
||||
|
|
@ -1624,6 +1672,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
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ public:
|
|||
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();
|
||||
|
|
@ -128,6 +129,9 @@ protected:
|
|||
virtual LLAvatarJoint* createAvatarJoint() = 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; }
|
||||
|
|
@ -144,6 +148,12 @@ public:
|
|||
|
||||
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);
|
||||
|
|
@ -158,12 +168,12 @@ protected:
|
|||
BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num);
|
||||
BOOL allocateCharacterJoints(S32 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;
|
||||
joint_alias_map_t mJointAliasMap;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Pelvis height adjustment members.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -231,7 +208,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
|
||||
|
|
@ -249,7 +226,6 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
// load data one line at a time
|
||||
//--------------------------------------------------------------------
|
||||
BOOL loadingGlobals = FALSE;
|
||||
Translation *trans = NULL;
|
||||
while ( getLine(fp) )
|
||||
{
|
||||
//----------------------------------------------------------------
|
||||
|
|
@ -276,13 +252,6 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
loadingGlobals = TRUE;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
loadingGlobals = FALSE;
|
||||
Translation &newTrans = mTranslations[ name ];
|
||||
trans = &newTrans;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
|
@ -504,173 +473,98 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
mConstraints.push_back(constraint);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// check for per-joint priority
|
||||
//----------------------------------------------------------------
|
||||
if ( LLStringUtil::compareInsensitive(token, "priority")==0 )
|
||||
{
|
||||
S32 priority;
|
||||
if ( sscanf(mLine, " %*s = %d", &priority) != 1 )
|
||||
return E_ST_NO_XLT_PRIORITY;
|
||||
|
||||
trans->mPriorityModifier = priority;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// LLBVHLoader::loadBVHFile()
|
||||
|
|
@ -751,6 +645,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--)
|
||||
{
|
||||
|
|
@ -782,12 +677,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
|
@ -795,11 +697,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;
|
||||
|
|
@ -868,6 +773,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
|
||||
//----------------------------------------------------------------
|
||||
|
|
@ -966,57 +886,41 @@ 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())
|
||||
{
|
||||
F32 val = boost::lexical_cast<float>(*float_token_iter);
|
||||
floats.push_back(val);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1339,6 +1243,9 @@ void LLBVHLoader::reset()
|
|||
mInitialized = FALSE;
|
||||
|
||||
mEmoteName = "";
|
||||
mLineNumber = 0;
|
||||
mTranslations.clear();
|
||||
mConstraints.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1595,5 +1502,6 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
|
|||
dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop");
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ public:
|
|||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,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() :
|
||||
|
|
@ -169,6 +171,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.
|
||||
|
|
|
|||
|
|
@ -40,9 +40,14 @@
|
|||
#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;
|
||||
// BENTO JOINT COUNT LIMIT - need to set this to final skeleton size + 2
|
||||
const U32 LL_CHARACTER_MAX_JOINTS = 144; // 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_JOINTS-1);
|
||||
const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_JOINTS-2);
|
||||
const S32 LL_CHARACTER_MAX_PRIORITY = 7;
|
||||
const F32 LL_MAX_PELVIS_OFFSET = 5.f;
|
||||
|
||||
|
|
@ -86,9 +91,17 @@ public:
|
|||
POSITION_DIRTY = 0x1 << 2,
|
||||
ALL_DIRTY = 0x7
|
||||
};
|
||||
public:
|
||||
enum SupportCategory
|
||||
{
|
||||
SUPPORT_BASE,
|
||||
SUPPORT_EXTENDED
|
||||
};
|
||||
protected:
|
||||
std::string mName;
|
||||
|
||||
SupportCategory mSupport;
|
||||
|
||||
// parent joint
|
||||
LLJoint *mParent;
|
||||
|
||||
|
|
@ -104,6 +117,10 @@ public:
|
|||
// 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
|
||||
|
|
@ -139,6 +156,15 @@ public:
|
|||
const std::string& getName() const { return mName; }
|
||||
void setName( const std::string &name ) { mName = name; }
|
||||
|
||||
// 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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1926,6 +1926,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");
|
||||
|
|
@ -1939,6 +1941,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);
|
||||
|
|
@ -1946,6 +1961,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)
|
||||
{
|
||||
|
|
@ -1963,6 +1979,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");
|
||||
|
|
@ -1981,37 +1999,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;
|
||||
|
|
@ -2029,6 +2064,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()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ public:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -111,9 +111,14 @@ 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_JOINTS) || (joint_num < 0))
|
||||
{
|
||||
LL_WARNS() << "joint_num " << joint_num << " is outside of legal range [0-" << LL_CHARACTER_MAX_JOINTS << ")" << LL_ENDL;
|
||||
}
|
||||
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 )
|
||||
|
|
|
|||
|
|
@ -576,7 +576,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]);
|
||||
|
|
|
|||
|
|
@ -4641,6 +4641,7 @@ LLVolumeFace::LLVolumeFace() :
|
|||
mTexCoords(NULL),
|
||||
mIndices(NULL),
|
||||
mWeights(NULL),
|
||||
mWeightsRemapped(FALSE),
|
||||
mOctree(NULL),
|
||||
mOptimized(FALSE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -956,6 +956,10 @@ public:
|
|||
// mWeights.size() should be empty or match mVertices.size()
|
||||
LLVector4a* mWeights;
|
||||
|
||||
// Whether or not the weights have been cleaned up and remapped
|
||||
// based on currently supported joints.
|
||||
mutable BOOL mWeightsRemapped;
|
||||
|
||||
LLOctreeNode<LLVolumeTriangle>* mOctree;
|
||||
|
||||
//whether or not face has been cache optimized
|
||||
|
|
|
|||
|
|
@ -833,15 +833,17 @@ 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)
|
||||
: LLModelLoader(
|
||||
filename,
|
||||
|
|
@ -851,8 +853,10 @@ LLDAELoader::LLDAELoader(
|
|||
texture_load_func,
|
||||
state_cb,
|
||||
opaque_userdata,
|
||||
jointMap,
|
||||
jointsFromNodes),
|
||||
jointTransformMap,
|
||||
jointsFromNodes,
|
||||
jointAliasMap,
|
||||
maxJointsPerMesh),
|
||||
mGeneratedModelLimit(modelLimit),
|
||||
mForceIdNaming(false)
|
||||
{
|
||||
|
|
@ -1257,6 +1261,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
|||
extractTranslation( pTranslateA, workingTransform );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pTranslateB )
|
||||
{
|
||||
extractTranslation( pTranslateB, workingTransform );
|
||||
|
|
@ -1281,9 +1286,10 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Store the joint transform w/respect to it's name.
|
||||
mJointList[(*jointIt).second.c_str()] = workingTransform;
|
||||
//Store the joint transform w/respect to its name.
|
||||
mJointList[(*jointIt).second.c_str()] = workingTransform;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1329,7 +1335,6 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
|||
name = mJointMap[name];
|
||||
}
|
||||
model->mSkinInfo.mJointNames.push_back(name);
|
||||
model->mSkinInfo.mJointMap[name] = j;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1347,7 +1352,6 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
|||
name = mJointMap[name];
|
||||
}
|
||||
model->mSkinInfo.mJointNames.push_back(name);
|
||||
model->mSkinInfo.mJointMap[name] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1375,8 +1379,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1392,35 +1395,40 @@ 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();
|
||||
//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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
// 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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //missingSkeletonOrScene
|
||||
|
||||
//We need to construct the alternate bind matrix (which contains the new joint positions)
|
||||
|
|
@ -1434,16 +1442,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1890,7 +1897,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,15 +47,17 @@ public:
|
|||
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);
|
||||
virtual ~LLDAELoader() ;
|
||||
|
||||
|
|
@ -105,6 +107,5 @@ protected:
|
|||
private:
|
||||
U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels
|
||||
bool mForceIdNaming;
|
||||
|
||||
};
|
||||
#endif // LL_LLDAELLOADER_H
|
||||
|
|
|
|||
|
|
@ -867,6 +867,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;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public:
|
|||
std::vector<std::string> mJointNames;
|
||||
std::vector<LLMatrix4> mInvBindMatrix;
|
||||
std::vector<LLMatrix4> mAlternateBindMatrix;
|
||||
std::map<std::string, U32> mJointMap;
|
||||
std::vector<U32> mJointRemap;
|
||||
|
||||
LLMeshSkinInfo() { }
|
||||
LLMeshSkinInfo(LLSD& data);
|
||||
|
|
|
|||
|
|
@ -104,16 +104,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)
|
||||
|
|
@ -126,88 +128,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";
|
||||
, mMaxJointsPerMesh(maxJointsPerMesh)
|
||||
, mJointMap(legalJointNamesMap)
|
||||
{
|
||||
|
||||
// <FS:Ansariel> FIRE-17144: Option to rig to attachment spots
|
||||
if (LLControlGroup::getInstance("Global")->getBOOL("FSEnableRiggingToAttachmentSpots"))
|
||||
|
|
@ -237,7 +165,6 @@ LLModelLoader::LLModelLoader(
|
|||
mJointMap["Left_Foot"] = "Left Foot";
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
//move into joint mapper class
|
||||
//1. joints for joint offset verification
|
||||
mMasterJointList.push_front("mPelvis");
|
||||
|
|
@ -507,8 +434,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
|
||||
|
|
@ -516,59 +441,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()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -580,68 +473,80 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs
|
|||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
// 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;
|
||||
}
|
||||
|
||||
JointSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin();
|
||||
JointSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end();
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Note that this is basically the same code as
|
||||
// isRigSuitableForJointPositionUpload(), but the set of joints is
|
||||
// different.
|
||||
JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin();
|
||||
JointNameSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end();
|
||||
|
||||
std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin();
|
||||
std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end();
|
||||
|
||||
|
||||
S32 missing_joint_count = 0;
|
||||
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;
|
||||
}
|
||||
if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd)
|
||||
{
|
||||
LL_INFOS() <<" Asset did not contain a joint required for skinned mesh upload: " << *masterJointIt<< LL_ENDL;
|
||||
missing_joint_count++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (missing_joint_count>0)
|
||||
{
|
||||
LL_WARNS() << "Skinning disabled due to missing joints" << LL_ENDL;
|
||||
}
|
||||
return missing_joint_count==0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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();
|
||||
JointNameSet :: const_iterator masterJointIt = mMasterJointList.begin();
|
||||
JointNameSet :: const_iterator masterJointEndIt = mMasterJointList.end();
|
||||
|
||||
std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin();
|
||||
std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end();
|
||||
|
||||
S32 missing_joint_count = 0;
|
||||
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;
|
||||
}
|
||||
if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd)
|
||||
{
|
||||
LL_INFOS() <<" Asset did not contain a joint required for joint position upload: " << *masterJointIt<< LL_ENDL;
|
||||
missing_joint_count++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (missing_joint_count>0)
|
||||
{
|
||||
LL_WARNS() << "Joint upload disabled due to missing joints" << LL_ENDL;
|
||||
}
|
||||
return missing_joint_count==0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,18 +116,21 @@ public:
|
|||
//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; }
|
||||
|
|
@ -158,7 +161,6 @@ public:
|
|||
|
||||
//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 +168,6 @@ public:
|
|||
//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; }
|
||||
|
||||
|
|
@ -189,17 +188,16 @@ protected:
|
|||
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;
|
||||
JointNameSet mMasterJointList;
|
||||
JointNameSet mMasterLegacyJointList;
|
||||
JointTransformMap mJointTransformMap;
|
||||
|
||||
static std::list<LLModelLoader*> sActiveLoaderList;
|
||||
|
|
|
|||
|
|
@ -658,6 +658,7 @@ set(viewer_SOURCE_FILES
|
|||
llsidepaneliteminfo.cpp
|
||||
llsidepaneltaskinfo.cpp
|
||||
llsidetraypanelcontainer.cpp
|
||||
llskinningutil.cpp
|
||||
llsky.cpp
|
||||
#llslurl.cpp #<FS:AW optional opensim support>
|
||||
llsnapshotlivepreview.cpp
|
||||
|
|
@ -1392,6 +1393,7 @@ set(viewer_HEADER_FILES
|
|||
llsidepaneliteminfo.h
|
||||
llsidepaneltaskinfo.h
|
||||
llsidetraypanelcontainer.h
|
||||
llskinningutil.h
|
||||
llsky.h
|
||||
llslurl.h
|
||||
llsnapshotlivepreview.h
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -5437,6 +5437,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>
|
||||
|
|
|
|||
|
|
@ -24,8 +24,11 @@
|
|||
|
||||
ATTRIBUTE vec4 weight4;
|
||||
|
||||
uniform mat3 matrixPalette[52];
|
||||
uniform vec3 translationPalette[52];
|
||||
/* BENTO JOINT COUNT LIMITS
|
||||
* Note that the value in these two lines also needs to be updated to value-1 several places below.
|
||||
*/
|
||||
uniform mat3 matrixPalette[MAX_JOINTS_PER_MESH_OBJECT];
|
||||
uniform vec3 translationPalette[MAX_JOINTS_PER_MESH_OBJECT];
|
||||
|
||||
mat4 getObjectSkinnedTransform()
|
||||
{
|
||||
|
|
@ -34,7 +37,7 @@ mat4 getObjectSkinnedTransform()
|
|||
vec4 w = fract(weight4);
|
||||
vec4 index = floor(weight4);
|
||||
|
||||
index = min(index, vec4(51.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);
|
||||
|
|
@ -67,8 +70,8 @@ mat4 getObjectSkinnedTransform()
|
|||
// 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];
|
||||
mat3 dummy3 = matrixPalette[MAX_JOINTS_PER_MESH_OBJECT-1];
|
||||
vec3 dummy4 = translationPalette[MAX_JOINTS_PER_MESH_OBJECT-1];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -73,7 +73,7 @@
|
|||
joint="mFootLeft"
|
||||
position="0 0.0 0.0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="8"
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
joint="mFootRight"
|
||||
position="0 0.0 0.0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="9"
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
joint="mChest"
|
||||
position="-0.15 0 -0.1"
|
||||
rotation="0 -90 90"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="10"
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
joint="mPelvis"
|
||||
position="0 0 -0.15"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="11"
|
||||
|
|
@ -113,8 +113,8 @@
|
|||
joint="mHead"
|
||||
position="0.12 0 0.001"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
<attachment_point
|
||||
id="12"
|
||||
group="2"
|
||||
|
|
@ -123,7 +123,7 @@
|
|||
joint="mHead"
|
||||
position="0.12 0 -0.04"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="13"
|
||||
|
|
@ -133,7 +133,7 @@
|
|||
joint="mHead"
|
||||
position="0.015 0.08 0.017"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="14"
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
joint="mHead"
|
||||
position="0.015 -0.08 0.017"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="15"
|
||||
|
|
@ -153,7 +153,7 @@
|
|||
joint="mEyeLeft"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false"/>
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
<attachment_point
|
||||
id="16"
|
||||
|
|
@ -163,7 +163,7 @@
|
|||
joint="mEyeRight"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="17"
|
||||
|
|
@ -173,7 +173,7 @@
|
|||
joint="mHead"
|
||||
position="0.1 0 0.05"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false"/>
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
<attachment_point
|
||||
id="18"
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
joint="mShoulderRight"
|
||||
position="0.01 -0.13 0.01"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="19"
|
||||
|
|
@ -193,7 +193,7 @@
|
|||
joint="mElbowRight"
|
||||
position="0 -0.12 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="20"
|
||||
|
|
@ -203,7 +203,7 @@
|
|||
joint="mShoulderLeft"
|
||||
position="0.01 0.15 -0.01"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="21"
|
||||
|
|
@ -213,7 +213,7 @@
|
|||
joint="mElbowLeft"
|
||||
position="0 0.113 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="22"
|
||||
|
|
@ -223,7 +223,7 @@
|
|||
joint="mHipRight"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="23"
|
||||
|
|
@ -233,7 +233,7 @@
|
|||
joint="mHipRight"
|
||||
position="-0.017 0.041 -0.310"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="24"
|
||||
|
|
@ -243,7 +243,7 @@
|
|||
joint="mKneeRight"
|
||||
position="-0.044 -0.007 -0.262"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="25"
|
||||
|
|
@ -253,8 +253,8 @@
|
|||
joint="mHipLeft"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="26"
|
||||
group="5"
|
||||
|
|
@ -263,7 +263,7 @@
|
|||
joint="mHipLeft"
|
||||
position="-0.019 -0.034 -0.310"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="27"
|
||||
|
|
@ -273,7 +273,7 @@
|
|||
joint="mKneeLeft"
|
||||
position="-0.044 -0.007 -0.261"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="28"
|
||||
|
|
@ -283,7 +283,7 @@
|
|||
joint="mPelvis"
|
||||
position="0.092 0.0 0.088"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="29"
|
||||
|
|
@ -293,7 +293,7 @@
|
|||
joint="mTorso"
|
||||
position="0.104 0.082 0.247"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="30"
|
||||
|
|
@ -303,11 +303,11 @@
|
|||
joint="mTorso"
|
||||
position="0.104 -0.082 0.247"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="31"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Center 2"
|
||||
joint="mScreen"
|
||||
position="0 0 0"
|
||||
|
|
@ -318,7 +318,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="32"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Top Right"
|
||||
joint="mScreen"
|
||||
position="0 -0.5 0.5"
|
||||
|
|
@ -329,7 +329,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="33"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Top"
|
||||
joint="mScreen"
|
||||
position="0 0 0.5"
|
||||
|
|
@ -340,7 +340,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="34"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Top Left"
|
||||
joint="mScreen"
|
||||
position="0 0.5 0.5"
|
||||
|
|
@ -351,7 +351,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="35"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Center"
|
||||
joint="mScreen"
|
||||
position="0 0 0"
|
||||
|
|
@ -362,7 +362,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="36"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Bottom Left"
|
||||
joint="mScreen"
|
||||
position="0 0.5 -0.5"
|
||||
|
|
@ -373,7 +373,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="37"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Bottom"
|
||||
joint="mScreen"
|
||||
position="0 0 -0.5"
|
||||
|
|
@ -384,7 +384,7 @@
|
|||
|
||||
<attachment_point
|
||||
id="38"
|
||||
group="8"
|
||||
group="9"
|
||||
name="Bottom Right"
|
||||
joint="mScreen"
|
||||
position="0 -0.5 -0.5"
|
||||
|
|
@ -413,6 +413,140 @@
|
|||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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="mFaceEarLeft"
|
||||
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="mFaceEarRight"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
position="0.000 0.000 0.000"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<!-- END BENTO -->
|
||||
|
||||
<param
|
||||
id="32"
|
||||
group="1"
|
||||
|
|
@ -478,6 +612,13 @@
|
|||
<bone
|
||||
name="mKneeRight"
|
||||
scale=".05 .05 .1" />
|
||||
|
||||
<bone name="mWingsRoot1" scale="1 0 0" offset="0 0 0" />
|
||||
<bone name="mWingsRoot2" scale="1 0 0" offset="0 0 0" />
|
||||
<bone name="mWingsRoot3" scale="1 0 0" offset="0 0 0" />
|
||||
<bone name="mWing1Right" scale="0 0 0" offset="0.02 0 0" />
|
||||
<bone name="mWing1Left" scale="0 0 0" offset="0.02 0 0" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -624,6 +765,17 @@
|
|||
<bone
|
||||
name="mKneeRight"
|
||||
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 0" />
|
||||
|
||||
<bone name="mWing1Right" offset="-0.01 -0.01 0" />
|
||||
<bone name="mWing1Left" offset="-0.01 0.01 0" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -662,6 +814,10 @@
|
|||
<bone
|
||||
name="mChest"
|
||||
scale="0.02 0.08 0" />
|
||||
|
||||
<bone name="mWing1Right" offset="0 -0.02 0" />
|
||||
<bone name="mWing1Left" offset="0 0.02 0" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -693,6 +849,11 @@
|
|||
name="mHipRight"
|
||||
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>
|
||||
|
||||
|
|
@ -774,6 +935,17 @@
|
|||
name="mEyeRight"
|
||||
scale="0 0 0"
|
||||
offset="0 -.009 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltLeft"
|
||||
scale="0 0 0 "
|
||||
offset="0 .009 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltRight"
|
||||
scale="0 0 0 "
|
||||
offset="0 -.009 0" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -797,6 +969,17 @@
|
|||
name="mEyeRight"
|
||||
scale="0 0 0"
|
||||
offset="0 0 -.004" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltLeft"
|
||||
scale="0 0 0"
|
||||
offset="0 0 .004" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltRight"
|
||||
scale="0 0 0"
|
||||
offset="0 0 -.004" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -820,6 +1003,17 @@
|
|||
name="mEyeRight"
|
||||
scale="0 0 0"
|
||||
offset=".016 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltLeft"
|
||||
scale="0 0 0"
|
||||
offset=".016 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltRight"
|
||||
scale="0 0 0"
|
||||
offset=".016 0 0" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -843,6 +1037,15 @@
|
|||
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" />
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -878,6 +1081,147 @@
|
|||
name="mEyeRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceForeheadLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceForeheadRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyebrowOuterLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyebrowCenterLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceEyebrowInnerLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
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="mFaceoseRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceCheekUpperInnerLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceCheekUpperOuterLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceCheekUpperInnerRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceCheekUpperOuterRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceJaw"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
name="mFaceLipUpperLeft"
|
||||
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="mFaceLipLowerRight"
|
||||
scale="1 1 1"
|
||||
offset="0 0 0" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -951,6 +1295,47 @@
|
|||
name="mWristLeft"
|
||||
scale="1 1 1"
|
||||
offset="0 0 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" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
@ -997,6 +1382,17 @@
|
|||
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" />
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,81 +1,192 @@
|
|||
<?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 num_bones="106" num_collision_volumes="26" version="2.0">
|
||||
<bone aliases="hip avatar_mPelvis" end="0.000 0.000 0.084" group="SL Base" 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" connected="false">
|
||||
<collision_volume end="0.020 0.000 0.100" 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 aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="SL Base" 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.020 0.000 0.100" 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 aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="SL Base" 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.080 0.000 0.180" 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.000" 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.000" 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="SL Base" 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="SL Base" 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="true" end="0.000 0.000 0.033" group="SL Base" 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" end="0.100 0.000 0.000" group="SL Base" 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" connected="false"/>
|
||||
<bone aliases="avatar_mEyeLeft" end="0.100 0.000 0.000" group="SL Base" 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" connected="false"/>
|
||||
<bone end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.086323 0.035081 0.128273" pos="0.086 0.035 0.128" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.086323 -0.035081 0.128273" pos="0.086 -0.035 0.128" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.027 0.000 0.000" group="Face" name="mFaceEyebrowOuterLeft" pivot="0.084314 0.064144 0.093192" pos="0.084 0.064 0.093" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.027 0.000 0.000" group="Face" name="mFaceEyebrowCenterLeft" pivot="0.095341 0.043099 0.101210" pos="0.095 0.043 0.101" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.027 -0.001 -0.001" group="Face" name="mFaceEyebrowInnerLeft" pivot="0.099350 0.023054 0.097201" pos="0.099 0.023 0.097" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.027 0.000 0.000" group="Face" name="mFaceEyebrowOuterRight" pivot="0.084314 -0.064144 0.093192" pos="0.084 -0.064 0.093" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.027 0.000 0.000" group="Face" name="mFaceEyebrowCenterRight" pivot="0.095341 -0.043099 0.101210" pos="0.095 -0.043 0.101" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.027 0.001 -0.001" group="Face" name="mFaceEyebrowInnerRight" pivot="0.099350 -0.023054 0.097201" pos="0.099 -0.023 0.097" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.038 0.000 0.000" group="Face" name="mFaceEyeLidUpperLeft" pivot="0.087323 0.036081 0.084174" pos="0.087 0.036 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.100 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.098486 0.036009 0.079020" pos="0.098 0.036 0.079" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.036 0.000 0.000" group="Face" name="mFaceEyeLidLowerLeft" pivot="0.086323 0.036081 0.072147" pos="0.086 0.036 0.072" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.038 0.000 0.000" group="Face" name="mFaceEyeLidUpperRight" pivot="0.087323 -0.036081 0.084174" pos="0.087 -0.036 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.100 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.098486 -0.036009 0.079020" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.036 0.000 0.000" group="Face" name="mFaceEyeLidLowerRight" pivot="0.086323 -0.036081 0.072147" pos="0.086 -0.036 0.072" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="-0.019 0.018 0.025" group="Face" name="mFaceEarLeft" pivot="0.025179 0.080180 0.047093" pos="0.025 0.080 0.047" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="-0.019 -0.018 0.025" group="Face" name="mFaceEarRight" pivot="0.025179 -0.080180 0.047093" pos="0.025 -0.080 0.047" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.007 0.005 0.002" group="Face" name="mFaceNoseLeft" pivot="0.121395 0.014036 0.045084" pos="0.121 0.014 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.031 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.121395 0.000000 0.045084" pos="0.121 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.007 -0.005 0.002" group="Face" name="mFaceNoseRight" pivot="0.121395 -0.014036 0.045084" pos="0.121 -0.014 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.018 0.004 -0.006" group="Face" name="mFaceCheekUpperInnerLeft" pivot="0.101350 0.044099 0.043084" pos="0.101 0.044 0.043" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.005 0.015 0.005" group="Face" name="mFaceCheekUpperOuterLeft" pivot="0.082314 0.057126 0.053102" pos="0.082 0.057 0.053" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.018 -0.004 -0.006" group="Face" name="mFaceCheekUpperInnerRight" pivot="0.101350 -0.044099 0.043084" pos="0.101 -0.044 0.043" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.005 -0.015 0.005" group="Face" name="mFaceCheekUpperOuterRight" pivot="0.082314 -0.057126 0.053102" pos="0.082 -0.057 0.053" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.053 0.004 -0.007" group="Face" name="mFaceLipUpperLeft" pivot="0.081305 0.011027 0.021030" pos="0.081 0.011 0.021" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.053 -0.004 -0.007" group="Face" name="mFaceLipUpperRight" pivot="0.081305 -0.011027 0.021030" pos="0.081 -0.011 0.021" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.037 -0.001 0.000" group="Face" name="mFaceLipCornerLeft" pivot="0.082314 0.033072 0.007002" pos="0.082 0.033 0.007" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.037 0.001 0.000" group="Face" name="mFaceLipCornerRight" pivot="0.082314 -0.033072 0.007002" pos="0.082 -0.033 0.007" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.045 0.000 -0.021" group="Face" name="mFaceJaw" pivot="0.044224 0.000000 0.008003" pos="0.044 0.000 0.008" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="0.020 0.000 0.008" group="Face" name="mFaceTongueBase" pivot="0.045000 0.000000 -0.021000" pos="0.045 0.000 -0.021" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="0.007 0.000 0.003" group="Face" name="mFaceTongueTip" pivot="0.020000 0.000000 0.008000" pos="0.020 0.000 0.008" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
<bone end="0.045 0.000 0.005" group="Face" name="mFaceLipLowerLeft" pivot="0.042000 0.017000 -0.021000" pos="0.042 0.017 -0.021" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
<bone end="0.045 0.000 0.005" group="Face" name="mFaceLipLowerRight" pivot="0.042000 -0.017000 -0.021000" pos="0.042 -0.017 -0.021" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone aliases="lCollar avatar_mCollarLeft" end="0.000 0.079 0.000" group="SL Base" 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" connected="false">
|
||||
<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="SL Base" 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.000" 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="SL Base" 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.000" 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="SL Base" 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.000 0.050 0.000" 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 end="-0.001 0.041 -0.004" group="Hand" name="mHandMiddle1Left" pivot="0.013427 0.099641 0.008427" pos="0.013 0.100 0.008" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.001 0.049 -0.006" group="Hand" name="mHandMiddle2Left" pivot="-0.000959 0.040656 -0.004287" pos="-0.001 0.041 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.002 0.033 -0.004" group="Hand" name="mHandMiddle3Left" pivot="-0.001476 0.048719 -0.005798" pos="-0.001 0.049 -0.006" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="0.019 0.042 -0.004" group="Hand" name="mHandIndex1Left" pivot="0.036416 0.091419 0.010424" pos="0.036 0.091 0.010" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="0.014 0.032 -0.004" group="Hand" name="mHandIndex2Left" pivot="0.019056 0.041560 -0.004473" pos="0.019 0.042 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="0.011 0.025 -0.003" group="Hand" name="mHandIndex3Left" pivot="0.014330 0.032011 -0.004359" pos="0.014 0.032 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="-0.013 0.039 -0.005" group="Hand" name="mHandRing1Left" pivot="-0.010432 0.098025 0.003099" pos="-0.010 0.098 0.003" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.013 0.040 -0.007" group="Hand" name="mHandRing2Left" pivot="-0.013326 0.038577 -0.005495" pos="-0.013 0.039 -0.005" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.010 0.028 -0.004" group="Hand" name="mHandRing3Left" pivot="-0.013398 0.039825 -0.006514" pos="-0.013 0.040 -0.007" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="-0.020 0.024 -0.004" group="Hand" name="mHandPinky1Left" pivot="-0.035119 0.095515 -0.001334" pos="-0.035 0.096 -0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.015 0.018 -0.003" group="Hand" name="mHandPinky2Left" pivot="-0.020450 0.023623 -0.003633" pos="-0.020 0.024 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.013 0.016 -0.003" group="Hand" name="mHandPinky3Left" pivot="-0.015199 0.018236 -0.003472" pos="-0.015 0.018 -0.003" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="0.028 0.030 0.001" group="Hand" name="mHandThumb1Left" pivot="0.035471 0.035681 -0.000635" pos="0.035 0.036 -0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="0.018 0.026 0.001" group="Hand" name="mHandThumb2Left" pivot="0.028355 0.029579 0.001081" pos="0.028 0.030 0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="0.016 0.024 0.001" group="Hand" name="mHandThumb3Left" pivot="0.017873 0.026014 0.000851" pos="0.018 0.026 0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone aliases="rCollar avatar_mCollarRight" end="0.000 -0.079 0.000" group="SL Base" 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" connected="false">
|
||||
<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="SL Base" 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.000" 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="SL Base" 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.000" 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="SL Base" 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.000 -0.050 0.000" 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 end="-0.001 -0.041 -0.004" group="Hand" name="mHandMiddle1Right" pivot="0.013427 -0.099641 0.008427" pos="0.013 -0.100 0.008" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.001 -0.049 -0.006" group="Hand" name="mHandMiddle2Right" pivot="-0.000959 -0.040656 -0.004287" pos="-0.001 -0.041 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.002 -0.033 -0.004" group="Hand" name="mHandMiddle3Right" pivot="-0.001476 -0.048719 -0.005798" pos="-0.001 -0.049 -0.006" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="0.019 -0.042 -0.004" group="Hand" name="mHandIndex1Right" pivot="0.036416 -0.091419 0.010424" pos="0.036 -0.091 0.010" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="0.014 -0.032 -0.004" group="Hand" name="mHandIndex2Right" pivot="0.019056 -0.041560 -0.004473" pos="0.019 -0.042 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="0.011 -0.025 -0.003" group="Hand" name="mHandIndex3Right" pivot="0.014330 -0.032011 -0.004359" pos="0.014 -0.032 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="-0.013 -0.039 -0.005" group="Hand" name="mHandRing1Right" pivot="-0.010432 -0.098025 0.003099" pos="-0.010 -0.098 0.003" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.013 -0.040 -0.007" group="Hand" name="mHandRing2Right" pivot="-0.013326 -0.038577 -0.005495" pos="-0.013 -0.039 -0.005" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.010 -0.028 -0.004" group="Hand" name="mHandRing3Right" pivot="-0.013398 -0.039825 -0.006514" pos="-0.013 -0.040 -0.007" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="-0.020 -0.024 -0.004" group="Hand" name="mHandPinky1Right" pivot="-0.035119 -0.095515 -0.001334" pos="-0.035 -0.096 -0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.015 -0.018 -0.003" group="Hand" name="mHandPinky2Right" pivot="-0.020450 -0.023623 -0.003633" pos="-0.020 -0.024 -0.004" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.013 -0.016 -0.003" group="Hand" name="mHandPinky3Right" pivot="-0.015199 -0.018236 -0.003472" pos="-0.015 -0.018 -0.003" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="0.028 -0.030 0.001" group="Hand" name="mHandThumb1Right" pivot="0.035471 -0.035681 -0.000635" pos="0.035 -0.036 -0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="0.018 -0.026 0.001" group="Hand" name="mHandThumb2Right" pivot="0.028355 -0.029579 0.001081" pos="0.028 -0.030 0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="0.016 -0.024 0.001" group="Hand" name="mHandThumb3Right" pivot="0.017873 -0.026014 0.000851" pos="0.018 -0.026 0.001" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="-0.015 0.000 0.000" group="Wing" name="mWingsRoot1" pivot="-0.014427 0.000057 -0.000108" pos="-0.014 0.000 -0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.020 0.000 0.000" group="Wing" name="mWingsRoot2" pivot="-0.015000 0.000000 0.000000" pos="-0.015 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.026 0.000 0.000" group="Wing" name="mWingsRoot3" pivot="-0.020095 0.000000 0.000000" pos="-0.020 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.063834 0.105140 0.181096" pos="-0.064 0.105 0.181" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.181 0.183 -0.000" group="Wing" name="mWing2Left" pivot="-0.167657 0.169194 0.066907" pos="-0.168 0.169 0.067" rot="0.000000 0.000000 0.000000" 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.181322 0.182984 -0.000120" pos="-0.181 0.183 -0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.028 0.029 0.000" group="Wing" name="mWing4Left" pivot="-0.170953 0.172520 -0.000113" pos="-0.171 0.173 -0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.063834 -0.105254 0.181096" pos="-0.064 -0.105 0.181" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.181 -0.183 -0.000" group="Wing" name="mWing2Right" pivot="-0.167657 -0.169194 0.066907" pos="-0.168 -0.169 0.067" rot="0.000000 0.000000 0.000000" 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.181322 -0.182984 -0.000120" pos="-0.181 -0.183 -0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.028 -0.029 0.000" group="Wing" name="mWing4Right" pivot="-0.170953 -0.172520 -0.000113" pos="-0.171 -0.173 -0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone aliases="rThigh avatar_mHipRight" end="-0.001 0.046 -0.491" group="SL Base" 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" connected="false">
|
||||
<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.001 -0.469" group="SL Base" 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="SL Base" 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.100 0.000 -0.020" 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.008 -0.000" group="SL Base" 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="true" end="0.020 0.000 0.000" group="SL Base" 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" end="-0.001 -0.046 -0.491" group="SL Base" 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" connected="false">
|
||||
<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="SL Base" 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="SL Base" 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.100 0.000 -0.020" 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="SL Base" 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="true" end="0.020 0.000 0.000" group="SL Base" 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 end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116417 0.000000 0.047423" pos="-0.116 0.000 0.047" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false">
|
||||
<bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197078 0.000000 0.000000" pos="-0.197 0.000 0.000" rot="0.000000 0.000000 0.000000" 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.168068 0.000000 0.000000" pos="-0.168 0.000 0.000" rot="0.000000 0.000000 0.000000" 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.142056 0.000000 0.000000" pos="-0.142 0.000 0.000" rot="0.000000 0.000000 0.000000" 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.112044 0.000000 0.000000" pos="-0.112 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
|
||||
<bone connected="true" end="-0.025 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094038 0.000000 0.000000" pos="-0.094 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
</bone>
|
||||
<bone end="0.004 0.000 -0.007" group="SL Extended" name="mGroin" pivot="0.064234 0.000000 -0.096868" pos="0.064 0.000 -0.097" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended" connected="false"/>
|
||||
</bone>
|
||||
</linden_skeleton>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
<?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>
|
||||
|
|
@ -116,6 +116,7 @@
|
|||
#include "llscenemonitor.h"
|
||||
#include "llavatarrenderinfoaccountant.h"
|
||||
#include "lllocalbitmaps.h"
|
||||
#include "llskinningutil.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llavatarnamecache.h"
|
||||
|
|
@ -970,6 +971,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"));
|
||||
|
|
@ -3311,7 +3315,7 @@ bool LLAppViewer::initConfiguration()
|
|||
//
|
||||
gWindowTitle = LLVersionInfo::getChannelAndVersion(); // <FS:CR>
|
||||
#if LL_DEBUG
|
||||
gWindowTitle += std::string(" [DEBUG]")
|
||||
gWindowTitle += std::string(" [DEBUG]");
|
||||
#endif
|
||||
if (!gArgs.empty())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lldrawpoolavatar.h"
|
||||
#include "llskinningutil.h"
|
||||
#include "llrender.h"
|
||||
|
||||
#include "llvoavatar.h"
|
||||
|
|
@ -63,8 +64,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;
|
||||
|
|
@ -1588,7 +1587,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)
|
||||
{
|
||||
// <FS:ND> FIRE-14261 try to skip broken or out of bounds faces
|
||||
if( vol_face.mNumVertices > 0x10000 || vol_face.mNumVertices < 0 || vol_face.mNumIndices < 0 )
|
||||
|
|
@ -1608,7 +1613,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);
|
||||
|
|
@ -1620,7 +1626,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);
|
||||
}
|
||||
|
||||
|
|
@ -1634,9 +1641,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);
|
||||
|
||||
|
|
@ -1674,26 +1681,37 @@ 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// FIXME ugly const cast
|
||||
LLSkinningUtil::remapSkinInfoJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
|
||||
|
||||
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
|
||||
LLDrawable* drawable = face->getDrawable();
|
||||
|
||||
U32 data_mask = face->getRiggedVertexBufferDataMask();
|
||||
|
||||
if (!vol_face.mWeightsRemapped)
|
||||
{
|
||||
LLSkinningUtil::remapSkinWeights(weight, vol_face.mNumVertices, skin);
|
||||
vol_face.mWeightsRemapped = TRUE;
|
||||
}
|
||||
|
||||
if (buffer.isNull() ||
|
||||
buffer->getTypeMask() != data_mask ||
|
||||
buffer->getNumVerts() != vol_face.mNumVertices ||
|
||||
|
|
@ -1744,85 +1762,19 @@ 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)
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL;
|
||||
}
|
||||
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(weight, buffer->getNumVerts(), skin);
|
||||
|
||||
LLMatrix4a bind_shape_matrix;
|
||||
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
|
||||
|
||||
__m128i _mMaxIdx = _mm_set_epi16( count-1, count-1, count-1, count-1, count-1, count-1, count-1, count-1 );
|
||||
|
||||
const U32 max_joints = LLSkinningUtil::getMaxJointCount();
|
||||
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
|
||||
{
|
||||
LLMatrix4a final_mat;
|
||||
final_mat.clear();
|
||||
|
||||
// <FS:ND> Avoid the 8 floorf by using SSE2.
|
||||
// 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;
|
||||
|
||||
LL_ALIGN_16( S32 idx[4] );
|
||||
LL_ALIGN_16( F32 wght[4] );
|
||||
|
||||
__m128i _mIdx = _mm_cvttps_epi32( weight[j] );
|
||||
__m128 _mWeight = _mm_sub_ps( weight[j], _mm_cvtepi32_ps( _mIdx ) );
|
||||
|
||||
_mIdx = _mm_min_epi16( _mIdx, _mMaxIdx );
|
||||
_mm_store_si128( (__m128i*)idx, _mIdx );
|
||||
|
||||
__m128 _mScale = _mm_add_ps( _mWeight, _mm_movehl_ps( _mWeight, _mWeight ));
|
||||
_mScale = _mm_add_ss( _mScale, _mm_shuffle_ps( _mScale, _mScale, 1) );
|
||||
_mScale = _mm_shuffle_ps( _mScale, _mScale, 0 );
|
||||
|
||||
_mWeight = _mm_div_ps( _mWeight, _mScale );
|
||||
_mm_store_ps( wght, _mWeight );
|
||||
// </FS:ND>
|
||||
|
||||
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(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
|
||||
|
||||
LLVector4a& v = vol_face.mPositions[j];
|
||||
LLVector4a t;
|
||||
|
|
@ -1902,34 +1854,21 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
if (buff)
|
||||
{
|
||||
if (sShaderLevel > 0)
|
||||
{ //upload matrix palette to shader
|
||||
LLMatrix4 mat[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);
|
||||
|
||||
U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT);
|
||||
|
||||
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 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*9];
|
||||
|
||||
F32 transp[JOINT_COUNT*3];
|
||||
F32 transp[LL_MAX_JOINTS_PER_MESH_OBJECT*3];
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -2110,30 +2049,21 @@ void LLDrawPoolAvatar::renderRiggedShadows(LLVOAvatar* avatar)
|
|||
if (buff)
|
||||
{
|
||||
if (sShaderLevel > 0)
|
||||
{ //upload matrix palette to shader
|
||||
LLMatrix4 mat[JOINT_COUNT];
|
||||
|
||||
U32 count = llmin((U32)skin->mJointNames.size(), (U32)JOINT_COUNT);
|
||||
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
{
|
||||
LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
|
||||
if (joint)
|
||||
{
|
||||
mat[i] = skin->mInvBindMatrix[i];
|
||||
mat[i] *= joint->getWorldMatrix();
|
||||
}
|
||||
}
|
||||
{
|
||||
// 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);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
F32 mp[JOINT_COUNT * 9];
|
||||
F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*9];
|
||||
|
||||
F32 transp[JOINT_COUNT * 3];
|
||||
F32 transp[LL_MAX_JOINTS_PER_MESH_OBJECT*3];
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -196,6 +196,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()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -279,6 +285,8 @@ BOOL LLFloaterBvhPreview::loadBVH()
|
|||
|
||||
getChildView("bad_animation_text")->setVisible(FALSE);
|
||||
|
||||
mAnimPreview = new LLPreviewAnimation(256, 256);
|
||||
|
||||
std::string exten = gDirUtilp->getExtension(mFilename);
|
||||
if (exten == "bvh")
|
||||
{
|
||||
|
|
@ -305,8 +313,11 @@ BOOL LLFloaterBvhPreview::loadBVH()
|
|||
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)
|
||||
|
|
@ -330,8 +341,6 @@ BOOL LLFloaterBvhPreview::loadBVH()
|
|||
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
|
||||
|
|
@ -361,9 +370,12 @@ BOOL LLFloaterBvhPreview::loadBVH()
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -124,11 +124,13 @@ public:
|
|||
// </FS:Sei>
|
||||
private:
|
||||
void setAnimCallbacks() ;
|
||||
std::map <std::string, std::string> getJointAliases();
|
||||
|
||||
// <FS> Reload animation from disk
|
||||
BOOL loadBVH();
|
||||
void unloadMotion();
|
||||
// </FS>
|
||||
|
||||
|
||||
protected:
|
||||
void draw();
|
||||
void resetMotion();
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -90,9 +90,6 @@
|
|||
// </AW: opensim-limits>
|
||||
#include "nd/ndboolswitch.h" // <FS:ND/> To toggle LLRender::sGLCoreProfile
|
||||
|
||||
// <FS:Ansariel> Proper matrix array length for fitted mesh
|
||||
#define JOINT_COUNT 52
|
||||
|
||||
#include "glod/glod.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
|
@ -273,6 +270,7 @@ mCalculateBtn(NULL)
|
|||
mLastMouseY = 0;
|
||||
mStatusLock = new LLMutex(NULL);
|
||||
mModelPreview = NULL;
|
||||
|
||||
mLODMode[LLModel::LOD_HIGH] = 0;
|
||||
for (U32 i = 0; i < LLModel::LOD_HIGH; i++)
|
||||
{
|
||||
|
|
@ -1241,7 +1239,6 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
|
|||
, mPhysicsSearchLOD( LLModel::LOD_PHYSICS )
|
||||
, mResetJoints( false )
|
||||
, mModelNoErrors( true )
|
||||
, mRigParityWithScene( false )
|
||||
, mLastJointUpdate( false )
|
||||
{
|
||||
mNeedsUpdate = TRUE;
|
||||
|
|
@ -1779,6 +1776,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();
|
||||
|
|
@ -1821,6 +1832,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,
|
||||
|
|
@ -1831,6 +1845,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
|
|||
this,
|
||||
mJointTransformMap,
|
||||
mJointsFromNode,
|
||||
joint_alias_map,
|
||||
LLSkinningUtil::getMaxJointCount(),
|
||||
gSavedSettings.getU32("ImporterModelLimit"));
|
||||
|
||||
if (force_disable_slm)
|
||||
|
|
@ -3419,19 +3435,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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -3569,6 +3572,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )
|
|||
pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// render()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -4062,20 +4066,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)
|
||||
|
|
@ -4100,70 +4090,32 @@ BOOL LLModelPreview::render()
|
|||
//quick 'n dirty software vertex skinning
|
||||
|
||||
//build matrix palette
|
||||
|
||||
// <FS:Ansariel> Proper matrix array length for fitted mesh
|
||||
//LLMatrix4 mat[64];
|
||||
//for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j)
|
||||
LLMatrix4 mat[JOINT_COUNT];
|
||||
U32 count = llmin((U32) model->mSkinInfo.mJointNames.size(), (U32) JOINT_COUNT);
|
||||
for (U32 j = 0; j < count; ++j)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
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++)
|
||||
{
|
||||
// <FS:Ansariel> Proper matrix array length for fitted mesh
|
||||
//F32* src = (F32*) mat[idx[k]].mMatrix;
|
||||
S32 l = idx[k];
|
||||
if( l >= JOINT_COUNT )
|
||||
l = 0;
|
||||
F32* src = (F32*) mat[l].mMatrix;
|
||||
// </FS:Ansariel>
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
// <FS:ND> FIRE-13465 Make sure there's a material set before dereferencing it
|
||||
|
|
@ -4186,7 +4138,6 @@ BOOL LLModelPreview::render()
|
|||
if (tex)
|
||||
{
|
||||
mTextureSet.insert(tex);
|
||||
|
||||
}
|
||||
|
||||
} else // <FS:ND> FIRE-13465 Make sure there's a material set before dereferencing it, if none, set buffer type and unbind texture.
|
||||
|
|
@ -4210,6 +4161,22 @@ BOOL LLModelPreview::render()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (joint_positions)
|
||||
{
|
||||
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
if (shader)
|
||||
{
|
||||
gDebugProgram.bind();
|
||||
}
|
||||
getPreviewAvatar()->renderCollisionVolumes();
|
||||
getPreviewAvatar()->renderBones();
|
||||
if (shader)
|
||||
{
|
||||
shader->bind();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4346,7 +4313,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();
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ public:
|
|||
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);
|
||||
void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
|
||||
|
|
@ -299,11 +300,7 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
protected:
|
||||
|
|
@ -350,7 +347,6 @@ private:
|
|||
bool mLoading;
|
||||
U32 mLoadState;
|
||||
bool mResetJoints;
|
||||
bool mRigParityWithScene;
|
||||
bool mModelNoErrors;
|
||||
|
||||
std::map<std::string, bool> mViewOption;
|
||||
|
|
@ -408,7 +404,7 @@ private:
|
|||
|
||||
bool mLastJointUpdate;
|
||||
|
||||
JointSet mJointsFromNode;
|
||||
JointNameSet mJointsFromNode;
|
||||
JointTransformMap mJointTransformMap;
|
||||
|
||||
LLPointer<LLVOAvatar> mPreviewAvatar;
|
||||
|
|
|
|||
|
|
@ -490,6 +490,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
|
|||
mCommitCallbackRegistrar.add("Pref.HardwareSettings", boost::bind(&LLFloaterPreference::onOpenHardwareSettings, this));
|
||||
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
|
||||
mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreference::onVertexShaderEnable, this));
|
||||
mCommitCallbackRegistrar.add("Pref.EnhancedSkeletonEnable", boost::bind(&LLFloaterPreference::onEnhancedSkeletonEnable, this, _1));
|
||||
mCommitCallbackRegistrar.add("Pref.LocalLightsEnable", boost::bind(&LLFloaterPreference::onLocalLightsEnable, this));
|
||||
mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
|
||||
mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::refreshUI,this));
|
||||
|
|
@ -1153,6 +1154,16 @@ void LLFloaterPreference::onVertexShaderEnable()
|
|||
refreshEnabledGraphics();
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onEnhancedSkeletonEnable(LLUICtrl *ctrl)
|
||||
{
|
||||
bool enabled = ctrl->getValue().asBoolean();
|
||||
bool curr_enabled = gSavedSettings.getBOOL("IncludeEnhancedSkeleton");
|
||||
if (enabled != curr_enabled)
|
||||
{
|
||||
gSavedSettings.setBOOL("IncludeEnhancedSkeleton",enabled);
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:AO> toggle lighting detail availability in response to local light rendering, to avoid confusion
|
||||
void LLFloaterPreference::onLocalLightsEnable()
|
||||
{
|
||||
|
|
@ -1871,7 +1882,11 @@ void LLFloaterPreference::refreshEnabledState()
|
|||
|
||||
// <FS:Ansariel> Radio group "ReflectionDetailRadio" doesn't exist as of 20/11/2012
|
||||
//radio_reflection_detail->setEnabled(reflections);
|
||||
|
||||
|
||||
LLCheckBoxCtrl* ctrl_enhanced_skel = getChild<LLCheckBoxCtrl>("AvatarEnhancedSkeleton");
|
||||
bool enhanced_skel_enabled = gSavedSettings.getBOOL("IncludeEnhancedSkeleton");
|
||||
ctrl_enhanced_skel->setValue(enhanced_skel_enabled);
|
||||
|
||||
// Avatar Mode
|
||||
// Enable Avatar Shaders
|
||||
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
|
||||
|
|
@ -2574,7 +2589,7 @@ void LLFloaterPreference::onClickAutoReplace()
|
|||
|
||||
void LLFloaterPreference::onClickSpellChecker()
|
||||
{
|
||||
LLFloaterReg::showInstance("prefs_spellchecker");
|
||||
LLFloaterReg::showInstance("prefs_spellchecker");
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onClickActionChange()
|
||||
|
|
|
|||
|
|
@ -138,6 +138,8 @@ protected:
|
|||
void setHardwareDefaults();
|
||||
// callback for when client turns on shaders
|
||||
void onVertexShaderEnable();
|
||||
// callback for when enhanced skeleton support checkbox toggled.
|
||||
void onEnhancedSkeletonEnable(LLUICtrl *ctrl);
|
||||
// <FS:AO> callback for local lights toggle
|
||||
void onLocalLightsEnable();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "lllineeditor.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lldatapacker.h"
|
||||
|
||||
extern LLAgent gAgent;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,354 @@
|
|||
/**
|
||||
* @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"
|
||||
|
||||
bool LLSkinningUtil::sIncludeEnhancedSkeleton = true;
|
||||
|
||||
namespace {
|
||||
|
||||
bool get_name_index(const std::string& name, std::vector<std::string>& names, U32& result)
|
||||
{
|
||||
std::vector<std::string>::const_iterator find_it =
|
||||
std::find(names.begin(), names.end(), name);
|
||||
if (find_it != names.end())
|
||||
{
|
||||
result = find_it - names.begin();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a name table index that is also a valid joint on the
|
||||
// avatar. Order of preference is: requested name, mPelvis, first
|
||||
// valid match in names table.
|
||||
U32 get_valid_joint_index(const std::string& name, LLVOAvatar *avatar, std::vector<std::string>& joint_names)
|
||||
{
|
||||
U32 result;
|
||||
if (avatar->getJoint(name) && get_name_index(name,joint_names,result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (get_name_index("mPelvis",joint_names,result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
for (U32 j=0; j<joint_names.size(); j++)
|
||||
{
|
||||
if (avatar->getJoint(joint_names[j]))
|
||||
{
|
||||
return j;
|
||||
}
|
||||
}
|
||||
// BENTO how to handle?
|
||||
LL_ERRS() << "no valid joints in joint_names" << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Which joint will stand in for this joint?
|
||||
U32 get_proxy_joint_index(U32 joint_index, LLVOAvatar *avatar, std::vector<std::string>& joint_names)
|
||||
{
|
||||
bool include_enhanced = LLSkinningUtil::sIncludeEnhancedSkeleton;
|
||||
U32 j_proxy = get_valid_joint_index(joint_names[joint_index], avatar, joint_names);
|
||||
LLJoint *joint = avatar->getJoint(joint_names[j_proxy]);
|
||||
llassert(joint);
|
||||
// Find the first ancestor that's not flagged as extended, or the
|
||||
// last ancestor that's rigged in this mesh, whichever
|
||||
// comes first.
|
||||
while (1)
|
||||
{
|
||||
if (include_enhanced ||
|
||||
joint->getSupport()==LLJoint::SUPPORT_BASE)
|
||||
break;
|
||||
LLJoint *parent = joint->getParent();
|
||||
if (!parent)
|
||||
break;
|
||||
if (!get_name_index(parent->getName(), joint_names, j_proxy))
|
||||
{
|
||||
break;
|
||||
}
|
||||
joint = parent;
|
||||
}
|
||||
return j_proxy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::initClass()
|
||||
{
|
||||
sIncludeEnhancedSkeleton = gSavedSettings.getBOOL("IncludeEnhancedSkeleton");
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLSkinningUtil::getMaxJointCount()
|
||||
{
|
||||
U32 result = LL_MAX_JOINTS_PER_MESH_OBJECT;
|
||||
if (!sIncludeEnhancedSkeleton)
|
||||
{
|
||||
// BENTO - currently the remap logic does not guarantee joint count <= 52;
|
||||
// if one of the base ancestors is not rigged in a given mesh, an extended
|
||||
// joint can still be included.
|
||||
result = llmin(result,(U32)52);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin)
|
||||
{
|
||||
return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size());
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
// Destructively remap the joints in skin info based on what joints
|
||||
// are known in the avatar, and which are currently supported. This
|
||||
// will also populate mJointRemap[] in the skin, which can be used to
|
||||
// make the corresponding changes to the integer part of vertex
|
||||
// weights.
|
||||
//
|
||||
// This will throw away joint info for any joints that are not known
|
||||
// in the avatar, or not currently flagged to support based on the
|
||||
// debug setting for IncludeEnhancedSkeleton.
|
||||
//
|
||||
|
||||
// BENTO maybe this really only makes sense for new leaf joints? New spine
|
||||
// joints may need different logic.
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin)
|
||||
{
|
||||
// skip if already done.
|
||||
if (!skin->mJointRemap.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U32 max_joints = getMeshJointCount(skin);
|
||||
|
||||
// Compute the remap
|
||||
std::vector<U32> j_proxy(skin->mJointNames.size());
|
||||
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
|
||||
{
|
||||
U32 j_rep = get_proxy_joint_index(j, avatar, skin->mJointNames);
|
||||
j_proxy[j] = j_rep;
|
||||
}
|
||||
S32 top = 0;
|
||||
std::vector<U32> j_remap(skin->mJointNames.size());
|
||||
// Fill in j_remap for all joints that will be kept.
|
||||
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
|
||||
{
|
||||
if (j_proxy[j] == j)
|
||||
{
|
||||
// Joint will be included
|
||||
j_remap[j] = top;
|
||||
if (top < max_joints-1)
|
||||
{
|
||||
top++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
// Then use j_proxy to fill in j_remap for the joints that will be discarded
|
||||
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
|
||||
{
|
||||
if (j_proxy[j] != j)
|
||||
{
|
||||
j_remap[j] = j_remap[j_proxy[j]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix
|
||||
std::vector<std::string> new_joint_names;
|
||||
std::vector<LLMatrix4> new_inv_bind_matrix;
|
||||
std::vector<LLMatrix4> new_alternate_bind_matrix;
|
||||
|
||||
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
|
||||
{
|
||||
if (j_proxy[j] == j && new_joint_names.size() < max_joints)
|
||||
{
|
||||
new_joint_names.push_back(skin->mJointNames[j]);
|
||||
new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]);
|
||||
if (!skin->mAlternateBindMatrix.empty())
|
||||
{
|
||||
new_alternate_bind_matrix.push_back(skin->mAlternateBindMatrix[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
llassert(new_joint_names.size() <= max_joints);
|
||||
|
||||
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "Starting joint[" << j << "] = " << skin->mJointNames[j] << " j_remap " << j_remap[j] << " ==> " << new_joint_names[j_remap[j]] << LL_ENDL;
|
||||
}
|
||||
|
||||
skin->mJointNames = new_joint_names;
|
||||
skin->mInvBindMatrix = new_inv_bind_matrix;
|
||||
skin->mAlternateBindMatrix = new_alternate_bind_matrix;
|
||||
skin->mJointRemap = j_remap;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::initSkinningMatrixPalette(
|
||||
LLMatrix4* mat,
|
||||
S32 count,
|
||||
const LLMeshSkinInfo* skin,
|
||||
LLVOAvatar *avatar)
|
||||
{
|
||||
// BENTO - switching to use Matrix4a and SSE might speed this up.
|
||||
// Note that we are mostly passing Matrix4a's to this routine anyway, just dubiously casted.
|
||||
for (U32 j = 0; j < count; ++j)
|
||||
{
|
||||
LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
|
||||
mat[j] = skin->mInvBindMatrix[j];
|
||||
if (joint)
|
||||
{
|
||||
mat[j] *= joint->getWorldMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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 remap.
|
||||
LL_WARNS_ONCE("Avatar") << "Rigged to invalid joint name " << skin->mJointNames[j] << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform the weights based on the remap info stored in skin. Note
|
||||
// that this is destructive and non-idempotent, so we need to keep
|
||||
// track of whether we've done it already. If the desired remapping
|
||||
// changes, the viewer must be restarted.
|
||||
//
|
||||
// static
|
||||
void LLSkinningUtil::remapSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
|
||||
{
|
||||
llassert(skin->mJointRemap.size()>0); // Must call remapSkinInfoJoints() first, which this checks for.
|
||||
const U32* remap = &skin->mJointRemap[0];
|
||||
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] = remap[i] + f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
|
||||
{
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
const S32 max_joints = skin->mJointNames.size();
|
||||
if (skin->mJointRemap.size()>0)
|
||||
{
|
||||
// Check the weights are consistent with the current remap.
|
||||
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]);
|
||||
llassert(i>=0);
|
||||
llassert(i<max_joints);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::getPerVertexSkinMatrix(
|
||||
F32* weights,
|
||||
LLMatrix4a* mat,
|
||||
bool handle_bad_scale,
|
||||
LLMatrix4a& final_mat,
|
||||
U32 max_joints)
|
||||
{
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @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 remapSkinInfoJoints(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 remapSkinWeights(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);
|
||||
|
||||
// This is initialized from gSavedSettings at startup and then left alone.
|
||||
static bool sIncludeEnhancedSkeleton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -3219,6 +3219,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)
|
||||
|
|
@ -3377,6 +3382,11 @@ public:
|
|||
renderAvatarCollisionVolumes(avatar);
|
||||
}
|
||||
|
||||
if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS))
|
||||
{
|
||||
renderAvatarBones(avatar);
|
||||
}
|
||||
|
||||
if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET))
|
||||
{
|
||||
renderAgentTarget(avatar);
|
||||
|
|
@ -3667,6 +3677,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 |
|
||||
|
|
|
|||
|
|
@ -1757,7 +1757,7 @@ bool idle_startup()
|
|||
LLPostProcess::initClass();
|
||||
display_startup();
|
||||
|
||||
LLAvatarAppearance::initClass();
|
||||
LLAvatarAppearance::initClass("avatar_lad.xml","avatar_skeleton.xml");
|
||||
display_startup();
|
||||
|
||||
LLViewerObject::initVOClasses();
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
#include "llvowlsky.h"
|
||||
#include "llrender.h"
|
||||
#include "llnavigationbar.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "llpaneloutfitsinventory.h"
|
||||
// <FS:Ansariel> [FS Login Panel]
|
||||
|
|
@ -164,6 +165,12 @@ static bool handleTerrainDetailChanged(const LLSD& newvalue)
|
|||
}
|
||||
|
||||
|
||||
static bool handleDeferredDebugSettingChanged(const LLSD& newvalue)
|
||||
{
|
||||
LLNotificationsUtil::add("ChangeDeferredDebugSetting");
|
||||
return true;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Expose handleSetShaderChanged()
|
||||
//static bool handleSetShaderChanged(const LLSD& newvalue)
|
||||
bool handleSetShaderChanged(const LLSD& newvalue)
|
||||
|
|
@ -1031,6 +1038,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("IncludeEnhancedSkeleton")->getCommitSignal()->connect(boost::bind(&handleDeferredDebugSettingChanged, _2));
|
||||
gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getSignal()->connect(boost::bind(&handleAvatarZOffsetChanged, _2)); // <FS:Zi> Moved Avatar Z offset from RLVa to here
|
||||
// <FS:Zi> Is done inside XUI now, using visibility_control
|
||||
// gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2));
|
||||
|
|
|
|||
|
|
@ -224,18 +224,18 @@ 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];
|
||||
|
||||
// ## Zi: Pie menu
|
||||
PieMenu* gPieAttachScreenMenu = NULL;
|
||||
PieMenu* gPieAttachMenu = NULL;
|
||||
PieMenu* gPieAttachBodyPartMenus[8];
|
||||
PieMenu* gPieAttachBodyPartMenus[9];
|
||||
PieMenu* gPieDetachMenu = NULL;
|
||||
PieMenu* gPieDetachScreenMenu = NULL;
|
||||
PieMenu* gPieDetachBodyPartMenus[8];
|
||||
PieMenu* gPieDetachBodyPartMenus[9];
|
||||
// ## Zi: Pie menu
|
||||
|
||||
LLMenuItemCallGL* gAutorespondMenu = NULL;
|
||||
|
|
|
|||
|
|
@ -213,8 +213,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];
|
||||
|
||||
// ## Zi: Pie Menu
|
||||
// Pie menus in 3D scene
|
||||
|
|
@ -231,8 +231,8 @@ extern PieMenu* gPieAttachScreenMenu;
|
|||
extern PieMenu* gPieDetachScreenMenu;
|
||||
extern PieMenu* gPieAttachMenu;
|
||||
extern PieMenu* gPieDetachMenu;
|
||||
extern PieMenu* gPieAttachBodyPartMenus[8];
|
||||
extern PieMenu* gPieDetachBodyPartMenus[8];
|
||||
extern PieMenu* gPieAttachBodyPartMenus[9];
|
||||
extern PieMenu* gPieDetachBodyPartMenus[9];
|
||||
// ## Zi: Pie Menu
|
||||
|
||||
extern LLMenuItemCallGL* gAutorespondMenu;
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
@ -873,7 +877,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++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -224,24 +224,6 @@ 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
|
||||
{
|
||||
|
|
@ -263,49 +245,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
|
||||
|
|
@ -1499,6 +1438,84 @@ void LLVOAvatar::renderCollisionVolumes()
|
|||
addDebugText(ostr.str());
|
||||
}
|
||||
|
||||
void LLVOAvatar::renderBones()
|
||||
{
|
||||
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
|
||||
std::ostringstream ostr;
|
||||
std::ostringstream nullstr;
|
||||
|
||||
avatar_joint_list_t::iterator iter = mSkeleton.begin();
|
||||
avatar_joint_list_t::iterator end = mSkeleton.end();
|
||||
|
||||
for (; iter != end; ++iter)
|
||||
{
|
||||
LLJoint* jointp = *iter;
|
||||
if (!jointp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ostr << jointp->getName() << ", ";
|
||||
|
||||
jointp->updateWorldMatrix();
|
||||
LLJoint::SupportCategory sc = jointp->getSupport();
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
|
||||
|
||||
gGL.begin(LLRender::LINES);
|
||||
|
||||
LLVector3 v[] =
|
||||
{
|
||||
LLVector3(0,0,0),
|
||||
LLVector3(0,0,0),
|
||||
};
|
||||
v[1] = jointp->getEnd();
|
||||
|
||||
LLGLDepthTest normal_depth(GL_TRUE);
|
||||
|
||||
// Unoccluded bone portions
|
||||
if (sc == LLJoint::SUPPORT_BASE)
|
||||
{
|
||||
gGL.diffuseColor3f( 1.0f, 0.5f, 0.5f );
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.diffuseColor3f( 0.5f, 1.0f, 0.5f );
|
||||
}
|
||||
|
||||
|
||||
gGL.vertex3fv(v[0].mV);
|
||||
gGL.vertex3fv(v[1].mV);
|
||||
|
||||
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
|
||||
|
||||
// Unoccluded bone portions
|
||||
if (sc == LLJoint::SUPPORT_BASE)
|
||||
{
|
||||
gGL.diffuseColor3f( 1.0f, 0.0f, 0.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.diffuseColor3f( 0.0f, 1.0f, 0.0f );
|
||||
}
|
||||
|
||||
gGL.vertex3fv(v[0].mV);
|
||||
gGL.vertex3fv(v[1].mV);
|
||||
|
||||
gGL.end();
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
mDebugText.clear();
|
||||
addDebugText(ostr.str());
|
||||
addDebugText(nullstr.str());
|
||||
}
|
||||
|
||||
|
||||
void LLVOAvatar::renderJoints()
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
|
@ -1608,7 +1625,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();
|
||||
|
|
@ -5746,7 +5763,10 @@ void LLVOAvatar::clearAttachmentPosOverrides()
|
|||
for (; iter != end; ++iter)
|
||||
{
|
||||
LLJoint* pJoint = (*iter);
|
||||
pJoint->clearAttachmentPosOverrides();
|
||||
if (pJoint)
|
||||
{
|
||||
pJoint->clearAttachmentPosOverrides();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6028,8 +6048,14 @@ BOOL LLVOAvatar::loadSkeletonNode ()
|
|||
LLViewerJointAttachment* attachment = new LLViewerJointAttachment();
|
||||
|
||||
attachment->setName(info->mName);
|
||||
LLJoint *parentJoint = getJoint(info->mJointName);
|
||||
if (!parentJoint)
|
||||
LLJoint *parent_joint = getJoint(info->mJointName);
|
||||
if (!parent_joint)
|
||||
{
|
||||
// If the intended location for attachment point is unavailable, stick it in a default location.
|
||||
LL_INFOS() << "attachment pt " << info->mName << " using mPelvis as default parent" << LL_ENDL;
|
||||
parent_joint = getJoint("mPelvis");
|
||||
}
|
||||
if (!parent_joint)
|
||||
{
|
||||
LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL;
|
||||
delete attachment;
|
||||
|
|
@ -6084,7 +6110,7 @@ BOOL LLVOAvatar::loadSkeletonNode ()
|
|||
mAttachmentPoints[attachmentID] = attachment;
|
||||
|
||||
// now add attachment joint
|
||||
parentJoint->addChild(attachment);
|
||||
parent_joint->addChild(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//
|
||||
|
|
@ -419,6 +417,7 @@ public:
|
|||
F32 getLastSkinTime() { return mLastSkinTime; }
|
||||
U32 renderTransparent(BOOL first_pass);
|
||||
void renderCollisionVolumes();
|
||||
void renderBones();
|
||||
void renderJoints();
|
||||
static void deleteCachedImages(bool clearAll=true);
|
||||
static void destroyGL();
|
||||
|
|
|
|||
|
|
@ -277,7 +277,6 @@ void LLVOAvatarSelf::initInstance()
|
|||
{
|
||||
mDebugBakedTextureTimes[i][0] = -1.0f;
|
||||
mDebugBakedTextureTimes[i][1] = -1.0f;
|
||||
mInitialBakeIDs[i] = LLUUID::null;
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-12-12 (RLVa-1.2.2c) | Added: RLVa-1.2.2c
|
||||
|
|
@ -445,6 +444,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"));
|
||||
|
|
@ -473,7 +476,11 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
params.name(params.label);
|
||||
gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
|
||||
|
||||
// ## Zi: Pie menu
|
||||
params.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
|
||||
params.name(params.label);
|
||||
gDetachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params);
|
||||
|
||||
// <FS:Zi> Pie menu
|
||||
//-------------------------------------------------------------------------
|
||||
// build the attach and detach pie menus
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
@ -507,6 +514,10 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
pieParams.name(pieParams.label);
|
||||
gPieAttachBodyPartMenus[7] = LLUICtrlFactory::create<PieMenu> (pieParams);
|
||||
|
||||
pieParams.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
|
||||
pieParams.name(pieParams.label);
|
||||
gPieAttachBodyPartMenus[8] = LLUICtrlFactory::create<PieMenu>(pieParams);
|
||||
|
||||
gPieDetachBodyPartMenus[0] = NULL;
|
||||
|
||||
pieParams.label(LLTrans::getString("BodyPartsRightArm"));
|
||||
|
|
@ -534,14 +545,24 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
pieParams.label(LLTrans::getString("BodyPartsRightLeg"));
|
||||
pieParams.name(pieParams.label);
|
||||
gPieDetachBodyPartMenus[7] = LLUICtrlFactory::create<PieMenu> (pieParams);
|
||||
// ## Zi: Pie menu
|
||||
|
||||
for (S32 i = 0; i < 8; i++)
|
||||
pieParams.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
|
||||
pieParams.name(pieParams.label);
|
||||
gPieDetachBodyPartMenus[8] = LLUICtrlFactory::create<PieMenu>(pieParams);
|
||||
// </FS:Zi> Pie menu
|
||||
|
||||
for (S32 i = 0; i < 9; i++)
|
||||
{
|
||||
if (gAttachBodyPartPieMenus[i])
|
||||
{
|
||||
gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] );
|
||||
gPieAttachMenu->appendContextSubMenu( gPieAttachBodyPartMenus[i] ); // ## Zi: Pie menu
|
||||
// <FS:Zi> Pie menu
|
||||
// Ansa: Exclude Bento additions for now until we figured out a way where to put them...
|
||||
if (i < 8)
|
||||
{
|
||||
gPieAttachMenu->appendContextSubMenu(gPieAttachBodyPartMenus[i]);
|
||||
}
|
||||
// </FS:Zi>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -576,16 +597,20 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
|
||||
gAttachPieMenu->addChild(item);
|
||||
|
||||
// ## Zi: Pie menu
|
||||
slice_params.name =(slice_params.label );
|
||||
slice_params.on_click.function_name = "Object.AttachToAvatar";
|
||||
slice_params.on_click.parameter = iter->first;
|
||||
slice_params.on_enable.function_name = "Object.EnableWear";
|
||||
slice_params.on_enable.parameter = iter->first;
|
||||
PieSlice* slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
// <FS:Zi> Pie menu
|
||||
// Ansa: Exclude Bento additions for now until we figured out a way where to put them...
|
||||
if (i < 8)
|
||||
{
|
||||
slice_params.name = (slice_params.label);
|
||||
slice_params.on_click.function_name = "Object.AttachToAvatar";
|
||||
slice_params.on_click.parameter = iter->first;
|
||||
slice_params.on_enable.function_name = "Object.EnableWear";
|
||||
slice_params.on_enable.parameter = iter->first;
|
||||
PieSlice* slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
|
||||
gPieAttachMenu->addChild(slice);
|
||||
// ## Zi: Pie menu
|
||||
gPieAttachMenu->addChild(slice);
|
||||
}
|
||||
// </FS:Zi> Pie menu
|
||||
|
||||
break;
|
||||
|
||||
|
|
@ -596,7 +621,13 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
if (gDetachBodyPartPieMenus[i])
|
||||
{
|
||||
gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] );
|
||||
gPieDetachMenu->appendContextSubMenu( gPieDetachBodyPartMenus[i] ); // ## Zi: Pie menu
|
||||
// <FS:Zi> Pie menu
|
||||
// Ansa: Exclude Bento additions for now until we figured out a way where to put them...
|
||||
if (i < 8)
|
||||
{
|
||||
gPieDetachMenu->appendContextSubMenu(gPieDetachBodyPartMenus[i]);
|
||||
}
|
||||
// </FS:Zi> Pie menu
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -608,17 +639,17 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
if (attachment->getGroup() == i)
|
||||
{
|
||||
LLMenuItemCallGL::Params item_params;
|
||||
PieSlice::Params slice_params; // ## Zi: Pie menu
|
||||
PieSlice::Params slice_params; // <FS:Zi> Pie menu
|
||||
std::string sub_piemenu_name = attachment->getName();
|
||||
if (LLTrans::getString(sub_piemenu_name) != "")
|
||||
{
|
||||
item_params.label = LLTrans::getString(sub_piemenu_name);
|
||||
slice_params.label = LLTrans::getString(sub_piemenu_name); // ## Zi: Pie menu
|
||||
slice_params.label = LLTrans::getString(sub_piemenu_name); // <FS:Zi> Pie menu
|
||||
}
|
||||
else
|
||||
{
|
||||
item_params.label = sub_piemenu_name;
|
||||
slice_params.label = sub_piemenu_name; // ## Zi: Pie menu
|
||||
slice_params.label = sub_piemenu_name; // <FS:Zi> Pie menu
|
||||
}
|
||||
item_params.name =(item_params.label );
|
||||
item_params.on_click.function_name = "Attachment.DetachFromPoint";
|
||||
|
|
@ -629,16 +660,20 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
|
||||
gDetachPieMenu->addChild(item);
|
||||
|
||||
// ## Zi: Pie menu
|
||||
slice_params.name =(slice_params.label );
|
||||
slice_params.on_click.function_name = "Attachment.DetachFromPoint";
|
||||
slice_params.on_click.parameter = iter->first;
|
||||
slice_params.on_enable.function_name = "Attachment.PointFilled";
|
||||
slice_params.on_enable.parameter = iter->first;
|
||||
PieSlice* slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
// <FS:Zi> Pie menu
|
||||
// Ansa: Exclude Bento additions for now until we figured out a way where to put them...
|
||||
if (i < 8)
|
||||
{
|
||||
slice_params.name = (slice_params.label);
|
||||
slice_params.on_click.function_name = "Attachment.DetachFromPoint";
|
||||
slice_params.on_click.parameter = iter->first;
|
||||
slice_params.on_enable.function_name = "Attachment.PointFilled";
|
||||
slice_params.on_enable.parameter = iter->first;
|
||||
PieSlice* slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
|
||||
gPieDetachMenu->addChild(slice);
|
||||
// ## Zi: Pie menu
|
||||
gPieDetachMenu->addChild(slice);
|
||||
}
|
||||
// </FS:Zi> Pie menu
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -652,7 +687,7 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
++iter)
|
||||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
if (attachment->getGroup() == 8)
|
||||
if (attachment->getGroup() == 9)
|
||||
{
|
||||
LLMenuItemCallGL::Params item_params;
|
||||
PieSlice::Params slice_params; // ## Zi: Pie menu
|
||||
|
|
@ -660,12 +695,12 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
if (LLTrans::getString(sub_piemenu_name) != "")
|
||||
{
|
||||
item_params.label = LLTrans::getString(sub_piemenu_name);
|
||||
slice_params.label = LLTrans::getString(sub_piemenu_name); // ## Zi: Pie menu
|
||||
slice_params.label = LLTrans::getString(sub_piemenu_name); // <FS:Zi> Pie menu
|
||||
}
|
||||
else
|
||||
{
|
||||
item_params.label = sub_piemenu_name;
|
||||
slice_params.label = sub_piemenu_name; // ## Zi: Pie menu
|
||||
slice_params.label = sub_piemenu_name; // <FS:Zi> Pie menu
|
||||
}
|
||||
item_params.name =(item_params.label );
|
||||
item_params.on_click.function_name = "Object.AttachToAvatar";
|
||||
|
|
@ -683,7 +718,7 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
|
||||
gDetachScreenPieMenu->addChild(item);
|
||||
|
||||
// ## Zi: Pie menu
|
||||
// <FS:Zi> Pie menu
|
||||
slice_params.name =(slice_params.label );
|
||||
slice_params.on_click.function_name = "Object.AttachToAvatar";
|
||||
slice_params.on_click.parameter = iter->first;
|
||||
|
|
@ -698,7 +733,7 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
slice_params.on_enable.parameter = iter->first;
|
||||
slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
gPieDetachScreenMenu->addChild(slice);
|
||||
// ## Zi: Pie menu
|
||||
// </FS:Zi> Pie menu
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -760,7 +795,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])
|
||||
|
|
@ -768,7 +803,8 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
continue;
|
||||
}
|
||||
|
||||
std::multimap<S32, S32> attachment_pie_menu_map; // ## Zi: Pie menu
|
||||
std::multimap<S32, S32> attachment_pie_menu_map;
|
||||
|
||||
// gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
|
||||
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
iter != mAttachmentPoints.end();
|
||||
|
|
@ -818,25 +854,29 @@ BOOL LLVOAvatarSelf::buildMenus()
|
|||
item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
|
||||
gDetachBodyPartPieMenus[group]->addChild(item);
|
||||
|
||||
// ## Zi: Pie menu
|
||||
PieSlice::Params slice_params;
|
||||
slice_params.name = attachment->getName();
|
||||
slice_params.label = LLTrans::getString(attachment->getName());
|
||||
slice_params.on_click.function_name = "Object.AttachToAvatar";
|
||||
slice_params.on_click.parameter = attach_index;
|
||||
slice_params.on_enable.function_name = "Object.EnableWear";
|
||||
slice_params.on_enable.parameter = attach_index;
|
||||
// <FS:Zi> Pie menu
|
||||
// Ansa: Exclude Bento additions for now until we figured out a way where to put them...
|
||||
if (group < 8)
|
||||
{
|
||||
PieSlice::Params slice_params;
|
||||
slice_params.name = attachment->getName();
|
||||
slice_params.label = LLTrans::getString(attachment->getName());
|
||||
slice_params.on_click.function_name = "Object.AttachToAvatar";
|
||||
slice_params.on_click.parameter = attach_index;
|
||||
slice_params.on_enable.function_name = "Object.EnableWear";
|
||||
slice_params.on_enable.parameter = attach_index;
|
||||
|
||||
PieSlice* slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
gPieAttachBodyPartMenus[group]->addChild(slice);
|
||||
PieSlice* slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
gPieAttachBodyPartMenus[group]->addChild(slice);
|
||||
|
||||
slice_params.on_click.function_name = "Attachment.DetachFromPoint";
|
||||
slice_params.on_click.parameter = attach_index;
|
||||
slice_params.on_enable.function_name = "Attachment.PointFilled";
|
||||
slice_params.on_enable.parameter = attach_index;
|
||||
slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
gPieDetachBodyPartMenus[group]->addChild(slice);
|
||||
// ## Zi: Pie menu
|
||||
slice_params.on_click.function_name = "Attachment.DetachFromPoint";
|
||||
slice_params.on_click.parameter = attach_index;
|
||||
slice_params.on_enable.function_name = "Attachment.PointFilled";
|
||||
slice_params.on_enable.parameter = attach_index;
|
||||
slice = LLUICtrlFactory::create<PieSlice>(slice_params);
|
||||
gPieDetachBodyPartMenus[group]->addChild(slice);
|
||||
}
|
||||
// </FS:Zi> Pie menu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3551,18 +3591,18 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
|
|||
LLViewerTexLayerSet *layerset = getTexLayerSet(i);
|
||||
if ( mBakedTextureDatas[i].mTextureIndex == te && layerset)
|
||||
{
|
||||
if (mInitialBakeIDs[i] != LLUUID::null)
|
||||
{
|
||||
if (mInitialBakeIDs[i] == uuid)
|
||||
{
|
||||
LL_INFOS() << "baked texture correctly loaded at login! " << i << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "baked texture does not match id loaded at login!" << i << LL_ENDL;
|
||||
}
|
||||
mInitialBakeIDs[i] = LLUUID::null;
|
||||
}
|
||||
//if (mInitialBakeIDs[i] != LLUUID::null)
|
||||
//{
|
||||
// if (mInitialBakeIDs[i] == uuid)
|
||||
// {
|
||||
// LL_INFOS() << "baked texture correctly loaded at login! " << i << LL_ENDL;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LL_WARNS() << "baked texture does not match id loaded at login!" << i << LL_ENDL;
|
||||
// }
|
||||
// mInitialBakeIDs[i] = LLUUID::null;
|
||||
//}
|
||||
layerset->cancelUpload();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,17 +116,6 @@ private:
|
|||
//BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight);
|
||||
BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE);
|
||||
|
||||
|
||||
|
||||
/** Initialization
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
private:
|
||||
LLUUID mInitialBakeIDs[6];
|
||||
//bool mInitialBakesLoaded;
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
** STATE
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -4277,27 +4278,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)
|
||||
{
|
||||
|
|
@ -4309,6 +4294,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);
|
||||
|
||||
|
|
@ -4318,59 +4304,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();
|
||||
|
||||
// <FS:ND> Avoid the 8 floorf by using SSE2.
|
||||
// Using _mm_cvttps_epi32 (truncate) under the assumption that the index can never be negative.
|
||||
|
||||
// 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;
|
||||
|
||||
LL_ALIGN_16( S32 idx[4] );
|
||||
LL_ALIGN_16( F32 wght[4] );
|
||||
|
||||
__m128i _mIdx = _mm_cvttps_epi32( weight[j] );
|
||||
__m128 _mWeight = _mm_sub_ps( weight[j], _mm_cvtepi32_ps( _mIdx ) );
|
||||
|
||||
_mm_store_si128( (__m128i*)idx, _mIdx );
|
||||
|
||||
__m128 _mScale = _mm_add_ps( _mWeight, _mm_movehl_ps( _mWeight, _mWeight ));
|
||||
_mScale = _mm_add_ss( _mScale, _mm_shuffle_ps( _mScale, _mScale, 1) );
|
||||
_mScale = _mm_shuffle_ps( _mScale, _mScale, 0 );
|
||||
|
||||
_mWeight = _mm_div_ps( _mWeight, _mScale );
|
||||
_mm_store_ps( wght, _mWeight );
|
||||
// </FS:ND>
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -4610,6 +4610,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">
|
||||
|
|
|
|||
|
|
@ -1454,6 +1454,13 @@ Sound cache will be moved after restarting [APP_NAME].
|
|||
Port settings take effect after restarting [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"
|
||||
|
|
@ -11462,6 +11469,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"
|
||||
|
|
|
|||
|
|
@ -768,6 +768,19 @@
|
|||
<check_box.commit_callback
|
||||
function="Pref.VertexShaderEnable" />
|
||||
</check_box>
|
||||
<check_box
|
||||
control_name="RenderAvatarEnhancedSkeleton"
|
||||
height="16"
|
||||
initial_value="true"
|
||||
label="Enhanced skeleton"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="AvatarEnhancedSkeleton"
|
||||
top_pad="1"
|
||||
width="256">
|
||||
<check_box.commit_callback
|
||||
function="Pref.EnhancedSkeletonEnable" />
|
||||
</check_box>
|
||||
<check_box
|
||||
control_name="RenderAvatarCloth"
|
||||
height="16"
|
||||
|
|
@ -787,7 +800,7 @@
|
|||
left="407"
|
||||
left_delta="200"
|
||||
name="TerrainDetailText"
|
||||
top_pad="-67"
|
||||
top_pad="-84"
|
||||
width="155">
|
||||
Terrain detail:
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -700,6 +700,7 @@ Please try logging in again in a minute.</string>
|
|||
<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>
|
||||
|
|
@ -925,8 +926,21 @@ 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="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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue